-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
✨ Add Grafana Plugin migration in alpha generate subcommand -- Step 2 #3509
Conversation
Hi @yyy1000. Thanks for your PR. I'm waiting for a kubernetes-sigs member to verify that this patch is reasonable to test. If it is, they should reply with Once the patch is verified, the new status will be reflected by the I understand the commands that are listed here. Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
err := store.Config().DecodePluginConfig(grafanaPluginKey, grafanaPlugin) | ||
// If the grafana plugin is not found, we don't need to migrate | ||
if errors.As(err, &config.PluginKeyNotFoundError{}) { | ||
return nil |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let us add an warning here, instead of skipping the migration silently.
pkg/rescaffold/migrate.go
Outdated
if errors.As(err, &config.PluginKeyNotFoundError{}) { | ||
return nil | ||
} | ||
if err != nil { | ||
return fmt.Errorf("Failed to Decode Grafana Plugin: %s. %v", grafanaPluginKey, err) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if errors.As(err, &config.PluginKeyNotFoundError{}) { | |
return nil | |
} | |
if err != nil { | |
return fmt.Errorf("Failed to Decode Grafana Plugin: %s. %v", grafanaPluginKey, err) | |
} | |
if err != nil { | |
if errors.As(err, &config.PluginKeyNotFound) { | |
// Add warning | |
return nil | |
} | |
return fmt.Errorf("failed to decode.....") | |
} | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, a small nit: why are we using errors.As
? Errors.As
checks if the error is of a particular type or follows an interface, errors.Is
is much safer if we know the exact error which is getting returned.
Could we modify it to be errors.Is
if we know what the error object contains?
Here is some doc to differentiate between the both.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, I just search the code repo and copy it. :)
kubebuilder/pkg/config/v3/config_test.go
Lines 420 to 429 in a5b246f
Expect(err).To(HaveOccurred()) | |
Expect(errors.As(err, &config.PluginKeyNotFoundError{})).To(BeTrue()) | |
}) | |
It("DecodePluginConfig should fail to retrieve data from a non-existent plugin", func() { | |
var pluginConfig PluginConfig | |
err := c1.DecodePluginConfig("plugin-y", &pluginConfig) | |
Expect(err).To(HaveOccurred()) | |
Expect(errors.As(err, &config.PluginKeyNotFoundError{})).To(BeTrue()) | |
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, after testing it. I think it should be errors.As
here. Changing it to Is
will fail. :)
Though I tried to add the key like '&config.PluginKeyNotFoundError{Key: grafanaPluginKey}' when using Is
, it still fails.
@@ -191,4 +204,11 @@ func ReGenerateProject(kbc *utils.TestContext) { | |||
filepath.Join(kbc.Dir, "testdir2", "PROJECT"), grafanaPlugin) | |||
ExpectWithOffset(1, err).NotTo(HaveOccurred()) | |||
ExpectWithOffset(1, fileContainsExpr).To(BeTrue()) | |||
|
|||
By("checking if the generated grafana config file has the same content as the old one") | |||
cmp := equalfile.New(nil, equalfile.Options{}) // compare using single mode |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Imo, let's not introduce a new dependency library, just for testing. Instead we can work with the helpers that gomega provides.
We can use BeARegularFile
(https://onsi.github.io/gomega/#bearegularfile) to check if the file exists. To check if the contents are equal, let's read them as bytes, and use gomega's BeEqualTo
(https://onsi.github.io/gomega/#equalexpected-interface).
cmp := equalfile.New(nil, equalfile.Options{}) // compare using single mode | ||
equal, err := cmp.CompareFile(filepath.Join(kbc.Dir, "testdir2", "grafana/custom-metrics/config.yaml"), | ||
filepath.Join(kbc.Dir, "grafana/custom-metrics/config.yaml")) | ||
ExpectWithOffset(1, err).NotTo(HaveOccurred()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need ExpectWithOffset
while comparing the error here? Can we just directly check the error? That would be easier and cleaner. Wdyt?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea. Acutally I'm still a little confused when should use this one. I think 'ExpectWithOffset' could provide the message about the 'call stack', so it will be used when in a function(maybe a layer of functions). And if not the case, we should use 'Expect'. Is it right?
equal, err := cmp.CompareFile(filepath.Join(kbc.Dir, "testdir2", "grafana/custom-metrics/config.yaml"), | ||
filepath.Join(kbc.Dir, "grafana/custom-metrics/config.yaml")) | ||
ExpectWithOffset(1, err).NotTo(HaveOccurred()) | ||
ExpectWithOffset(1, equal).To(BeTrue()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, with this one. We may not need ExpectWithOffset
.
/ok-to-test |
pkg/rescaffold/migrate.go
Outdated
if err != nil { | ||
return fmt.Errorf("Failed to Decode Grafana Plugin: %s. %v", grafanaPluginKey, err) | ||
} | ||
err = kubebuilderGrafanaEdit() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Question:
Why do we need to run kubebuilderGrafanaEdit
in such circumstance where:
the PluginChain does not contain
grafana-plugin
but thegrafana-plugin
can loaded from the config?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First, in my understanding, GetPluginChain() method will return the 'layout' field in the PROJECT file, but not plugins field. Correct me if wrong. @camilamacedo86 @varshaprasad96
In this case, if we don't run kubebuilder init --plugins grafana.kubebuilder.io/v1-alpha
, but run 'edit' when the project has been inited. The PluginChain will not contain the grafana plugin('layout' field), but it will appears in 'plugins' field. So we need to call 'edit' and 'copy file'.
But if we init the project using two plugins, (or only the grafana plugin itself). The layout field will contain 'grafana plugin', which could be retrieved by 'GetPluginChain()' methond. Since we will also init the new project with all plugins. We don't need to call 'edit', but need to 'copy file'.
Does it make sense?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you find the Grafana plugin in the PROJECT file then you must to:
- When you run kb init use the plugin
- After copy the file which has custom metrics config option for it in the new directory where the project was scaffolded
- Then, run kb edit with the plugin so that if custom metrics were setup for it then, you will also re-generate them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm thinking if the logic can be something like:
- If the origin PROJECT file does not contain the Grafana plugin, then exit
- If the origin PROJECT file contains the Grafana plugin, which means the origin project uses it:
2.1 Runedit ...plugin ...grafana
to generate the basic grafana dir
2.2 Copy the config.yaml to the new scaffold
2.3 Runedit ...plugin ...grafana
again to generate additional files.
I am imagining if we can get free from the 'complicated' logic...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool! That's much clearer. I didn't understand 'edit' command before.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 Agreed with @Kavinjsir's logic. If the plugin doesn't exist in the origin PROJECT file, then we need to run the edit command. We can exit immediately.
4839ab6
to
f1ed132
Compare
feat: reafactor code due to suggestions feat: revert unused import in mod file fix: add warning and fix test cases fix: golang lint feat: adjust work flow and revert slice dependency
f1ed132
to
7c1ca0d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All suggestions are in place!!!
Great work 🥇
So, that seems good to fly
/lgtm |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/lgtm
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: camilamacedo86, Kavinjsir, varshaprasad96, yyy1000 The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
/test pull-kubebuilder-e2e-k8s-1-27-1 |
Description:
Support Grafana Plugin migration in the alpha generate subcommand.
This is the second step, which will copy the config.yaml in metrics.