Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Does operator v5 support jsonnet/libraries? #1292

Closed
vchirikov opened this issue Oct 31, 2023 · 14 comments
Closed

Does operator v5 support jsonnet/libraries? #1292

vchirikov opened this issue Oct 31, 2023 · 14 comments
Labels

Comments

@vchirikov
Copy link

Hi guys, I'm working on migration from v4 to v5 and it's time to figure out how to work with libsonnet library. I use rhowe-grafonnet fork and want to provide their version of grafonnet to generate dashboards.
I saw awesome work of @olejeglejeg with external libs, but I want to reuse libsonnet code over multiple dashboards, so I think it's not a good solution to tar.gz all dashboards with same dependency multiple times (instead of reuse them).

I found on API Reference that LibraryLabelSelector is still there, but I didn't find any examples of this in v5.

Does it work in v5?

If it's not I'm ok with mounting config map into operator's fs, like:

  volumeMounts:
    - name: dashboards-dir
      mountPath: /tmp/dashboards
    - name: rhowe-grafonnet
      mountPath: /vendor/rhowe-grafonnet
volumes:
  - name: rhowe-grafonnet
    configMap:
      name: rhowe-grafonnet
      optional: false
  - name: dashboards-dir
    emptyDir: {}

but in current api spec of grafana dashboard I can't use jPath without gzip :( As a workaround I can try to gzip only the dashboard itself and provide jPath as /vendor, but it will be great to have an option to use jPath without gzip. What do you think?

@vchirikov
Copy link
Author

vchirikov commented Nov 1, 2023

Ok, I tried with gzip & jPath to /vendor and it doesn't work (can't import file no match locally or in the Jsonnet library paths even if jPath: /vendor is there), so I tried to import directly:

  jsonnet: |-
    local thm = import '/vendor/rhowe-grafonnet/thm.libsonnet';

but it cause a bug in fetcher:

INTERNAL ERROR: (CRASH) runtime error: invalid memory address or nil pointer dereference

INTERNAL ERROR: (CRASH) runtime error: invalid memory address or nil pointer dereference
goroutine 296 [running]:
runtime/debug.Stack()
	runtime/debug/stack.go:24 +0x65
github.com/google/go-jsonnet.(*VM).evaluateSnippet.func1()
	github.com/google/go-jsonnet@v0.20.0/vm.go:214 +0x45
panic({0x17b5c60, 0x28e7440})
	runtime/panic.go:884 +0x213
github.com/google/go-jsonnet.Contents.Data(...)
	github.com/google/go-jsonnet@v0.20.0/imports.go:75
github.com/grafana-operator/grafana-operator/v5/controllers/fetchers.(*EmbedFSImporter).Import(0xc0015281c8, {0x65757165725f6563?, 0x7b6d75733a737473?}, {0xc001264540, 0x25})
	github.com/grafana-operator/grafana-operator/v5/controllers/fetchers/jsonnet_fetcher.go:86 +0x256
github.com/google/go-jsonnet.(*importCache).importData(0xc001502ba0, {0x0?, 0x46223a2264496665?}, {0xc001264540?, 0x616e286d7573223a?})
	github.com/google/go-jsonnet@v0.20.0/imports.go:122 +0x3b
github.com/google/go-jsonnet.(*importCache).importAST(0xc001502ba0, {0x0?, 0x61466c6176726574?}, {0xc001264540?, 0x313a227065747322?})
	github.com/google/go-jsonnet@v0.20.0/imports.go:137 +0x32
github.com/google/go-jsonnet.(*importCache).importCode(0xc001502ba0, {0x0?, 0x7073656d616e2820?}, {0xc001264540?, 0x73656d616e286d75?}, 0xc00111ad90)
	github.com/google/go-jsonnet@v0.20.0/imports.go:196 +0x4b
github.com/google/go-jsonnet.(*interpreter).evaluate(0xc00111ad90, {0x1cdf518, 0xc000607880?}, 0xc00160e578?)
	github.com/google/go-jsonnet@v0.20.0/interpreter.go:484 +0x163f
github.com/google/go-jsonnet.(*interpreter).EvalInCleanEnv(0xc00111ad90, 0x2b1ca78?, {0x1cdf518, 0xc000607880}, 0x40?)
	github.com/google/go-jsonnet@v0.20.0/interpreter.go:983 +0x70
github.com/google/go-jsonnet.(*cachedThunk).getValue(0xc0013bfc40, 0xc0004b893c?)
	github.com/google/go-jsonnet@v0.20.0/thunks.go:74 +0x53
github.com/google/go-jsonnet.(*interpreter).evaluate(0xc00111ad90, {0x1cdf9e0, 0xc000607900?}, 0x0?)
	github.com/google/go-jsonnet@v0.20.0/interpreter.go:538 +0x1cd6
github.com/google/go-jsonnet.(*interpreter).evaluate(0xc00111ad90, {0x1cdf638, 0xc000fe3ad0?}, 0xc00160f7d8?)
	github.com/google/go-jsonnet@v0.20.0/interpreter.go:448 +0xfe9
github.com/google/go-jsonnet.(*interpreter).evaluate(0xc00111ad90, {0x1cdf638, 0xc000fe3ba0?}, 0x14f2af4?)
	github.com/google/go-jsonnet@v0.20.0/interpreter.go:448 +0xfe9
github.com/google/go-jsonnet.(*interpreter).evaluate(0xc00111ad90, {0x1cdf200, 0xc001275400?}, 0x3?)
	github.com/google/go-jsonnet@v0.20.0/interpreter.go:570 +0x212b
github.com/google/go-jsonnet.(*interpreter).evaluate(0xc00111ad90, {0x1cdf7a0, 0xc000141400?}, 0x0?)
	github.com/google/go-jsonnet@v0.20.0/interpreter.go:527 +0x2f65
github.com/google/go-jsonnet.(*interpreter).EvalInCleanEnv(0xc00111ad90, 0x0?, {0x1cdf7a0, 0xc000141400}, 0x0?)
	github.com/google/go-jsonnet@v0.20.0/interpreter.go:983 +0x70
github.com/google/go-jsonnet.evaluateAux(0xc00111ad90, {0x1cdf7a0, 0xc000141400}, 0xc001502ba0?)
	github.com/google/go-jsonnet@v0.20.0/interpreter.go:1290 +0x19b
github.com/google/go-jsonnet.evaluate({0x1cdf7a0, 0xc000141400}, 0x16104e7?, 0xc0004b8900?, 0x18f5ea0?, 0xc001497ec0?, 0x2aec8c0?, {0x1cc6c60?, 0xc000122010?}, 0x0)
	github.com/google/go-jsonnet@v0.20.0/interpreter.go:1325 +0x8d
github.com/google/go-jsonnet.(*VM).evaluateSnippet(0xc0016116e0, {0xc001360ba0?, 0xc0001bf800?}, {0x0?, 0x0?}, {0xc0004b8900?, 0x40e147?}, 0x0)
	github.com/google/go-jsonnet@v0.20.0/vm.go:223 +0x1e5
github.com/google/go-jsonnet.(*VM).EvaluateAnonymousSnippet(0xc0016116e0, {0xc001360ba0?, 0x30?}, {0xc0004b8900?, 0x0?})
	github.com/google/go-jsonnet@v0.20.0/vm.go:371 +0x39
github.com/grafana-operator/grafana-operator/v5/controllers/fetchers.FetchJsonnet(0xc00121c780, 0x1cdcd50?, {0xc001351c80?})
	github.com/grafana-operator/grafana-operator/v5/controllers/fetchers/jsonnet_fetcher.go:109 +0x4cf
github.com/grafana-operator/grafana-operator/v5/controllers.(*GrafanaDashboardReconciler).fetchDashboardJson(0xc00009df40, {0x1cdcd50, 0xc001351c80}, 0xc00121c780)
	github.com/grafana-operator/grafana-operator/v5/controllers/dashboard_controller.go:451 +0x1c7
github.com/grafana-operator/grafana-operator/v5/controllers.(*GrafanaDashboardReconciler).Reconcile(0xc00009df40, {0x1cdcd50, 0xc001351c80}, {{{0xc000fcef25?, 0x5?}, {0xc000fb44c0?, 0xc001611d48?}}})
	github.com/grafana-operator/grafana-operator/v5/controllers/dashboard_controller.go:194 +0x6aa
sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).Reconcile(0x1cdf0e0?, {0x1cdcd50?, 0xc001351c80?}, {{{0xc000fcef25?, 0xb?}, {0xc000fb44c0?, 0x0?}}})
	sigs.k8s.io/controller-runtime@v0.16.1/pkg/internal/controller/controller.go:119 +0xc8
sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).reconcileHandler(0xc00019b2c0, {0x1cdcca8, 0xc0004beaa0}, {0x1834680?, 0xc000477620?})
	sigs.k8s.io/controller-runtime@v0.16.1/pkg/internal/controller/controller.go:316 +0x3ca
sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).processNextWorkItem(0xc00019b2c0, {0x1cdcca8, 0xc0004beaa0})
	sigs.k8s.io/controller-runtime@v0.16.1/pkg/internal/controller/controller.go:266 +0x1d9
sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).Start.func2.2()
	sigs.k8s.io/controller-runtime@v0.16.1/pkg/internal/controller/controller.go:227 +0x85
created by sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).Start.func2
	sigs.k8s.io/controller-runtime@v0.16.1/pkg/internal/controller/controller.go:223 +0x587


upd:

https://github.com/grafana-operator/grafana-operator/blob/7f4ee5942f588da959c3fcaf67b25ddfc98c2d83/controllers/fetchers/jsonnet_fetcher.go#L107C15-L107C30

Looks like for jsonnet there is only embed fs importer T_T

@vchirikov
Copy link
Author

I found a bit hacky workaround, because it uses security issue here (you can leave unpacked-sandbox directory):

https://github.com/grafana-operator/grafana-operator/blob/7f4ee5942f588da959c3fcaf67b25ddfc98c2d83/controllers/fetchers/jsonnet_fetcher.go#L189-L191

you could mount configmap with libsonnet with k8s mounts and then use

  jsonnetLib:
    jPath:
      - ./../../../vendor

something like this to get access to the mounted files..

@pb82
Copy link
Collaborator

pb82 commented Nov 7, 2023

@vchirikov v5 currently only supports the main Grafonnet library (which is bundled). No external libraries are supported. @HubertStefanski is that still correct?

@vchirikov
Copy link
Author

we should remove Grafana.spec.jsonnet.libraryLabelSelector from CRD / docs / code then

@NissesSenap
Copy link
Collaborator

NissesSenap commented Nov 14, 2023

@vchirikov
Copy link
Author

It's close, but to use THE SAME library in 100 dashboards I need to create 100 tar.gz with THE SAME library. I want to reuse the libsonnet code. For now I can reuse it only with hacky workaround. I think it will be nice to provide a way to add libsonnet code without duplicating it inside archives, e.g. add the real FS importer in jsonnet fetcher (now it's EmbedFSImporter only there).

@NissesSenap
Copy link
Collaborator

So none of the maintainers use or know jsonnet (this might change soon), but we have relied a lot on the community and its feedback when it comes to jsonnet implementations.

So I will do that once again.
@olejeglejeg what are your thoughts in this area?

@NissesSenap
Copy link
Collaborator

@vchirikov if you have an idea on how this could be solved, we would also love to see a PR around it. Preferably not a breaking change, but if it's needed we can do that as well as long as we can get feedback from multiple jsonnet users.

@ljuaneda
Copy link

@pb82 @HubertStefanski is there a clear status on the jsonnet library support ?
what is the purpose of Grafana.spec.jsonnet.libraryLabelSelector ?

I'm also trying to migrate from v4 and I was using libraryLabelSelector to reference custom jsonnet libraries I've developped.
this isn't working with v5

@sebhoss
Copy link

sebhoss commented Jan 13, 2024

not sure how this worked in v4, but how about introducing two new custom resources for cluster- and namespace-scoped jsonnet libraries and allow them to be referenced in the existing GrafanaDashboard resources? A example could look like this:

apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaDashboard
metadata:
  name: grafanadashboard-jsonnet
spec:
  jsonnetLibaries:
    - name: namespaced-lib
      kind: JsonnetLibrary
    - name: cluster-scoped-lib
      kind: ClusterJsonnetLibrary
  jsonnet: |
   local grafana = import 'grafonnet/grafana.libsonnet';
   local namespaced = import 'namespaced-lib';
   local cluster = import 'cluster-scoped-lib';
   ...

The individual jsonnet library resources could use the existing tar.gz based approach but would allow re-use of of those blobs across multiple dashboards.

Copy link

This issue hasn't been updated for a while, marking as stale, please respond within the next 7 days to remove this label

@github-actions github-actions bot added the stale label Feb 13, 2024
@sebhoss
Copy link

sebhoss commented Feb 13, 2024

would still love to have this

@github-actions github-actions bot removed the stale label Feb 14, 2024
@NissesSenap
Copy link
Collaborator

If anyone can come up with a design document that describes how you want this to work, it would be great.
From there, an implementation can be done.
Take a look in https://github.com/grafana/grafana-operator/tree/master/docs/docs/proposals for inspiration.

Copy link

This issue hasn't been updated for a while, marking as stale, please respond within the next 7 days to remove this label

@github-actions github-actions bot added the stale label Mar 26, 2024
@github-actions github-actions bot closed this as not planned Won't fix, can't repro, duplicate, stale Apr 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants