-
Notifications
You must be signed in to change notification settings - Fork 566
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
double render the helmfile #308
double render the helmfile #308
Conversation
Hey @davidovich, your solution seems very interesting! I love how this makes helmfile.yaml cleaner and easier to read/write in case we want to reference environment values(not variables) in helmfile.yaml. However, I'm a bit unsure if there's any bad side-effect of doing it in such way. I thought that helmfile would end up executing So maybe there's nothing concrete that is preventing us from merging this, and closing #254 #297 in favor of this? @Stono @osterman @sstarcher I'd appreciate your comments on this, too! |
Seems like a plausible way to support the values directly. |
main.go
Outdated
@@ -554,10 +554,22 @@ func findAndIterateOverDesiredStates(fileOrDir string, converge func(*state.Helm | |||
noTargetFoundForAllHelmfiles := true | |||
for _, f := range desiredStateFiles { | |||
logger.Debugf("Processing %s", f) | |||
yamlBuf, err := tmpl.NewFileRenderer(ioutil.ReadFile, "", environment.EmptyEnvironment).RenderTemplateFileToBuffer(f) | |||
|
|||
fileRenderer := tmpl.NewFileRenderer(nil, "", environment.EmptyEnvironment) |
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 suspect if the nil
as the first argument here makes any readFile
call inside helmfile.yaml fail at first pass.
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.
Fixed it in 2072ede
I've added some debug logs while fixing the |
One gotcha is that something like the below blows up helmfile on first-pass render with
because the environment value isn't loaded yet hence A work-around is to modify it by adding a nil-check:
|
Could this lead to a difference in rendering if readFile or exec would return different information on the second call (think about a timestamp or a randomly generated password)? Some parts of the template using the value from the first call and some parts of the template using the value from the second call for example? |
Yes, if template functions have side effects, they would be executed twice. I am searching for a way to ignore, or make null operations for the first pass, as this first pass is only meant to parse the environment which is to be re-injected. I was not aware of the new execution functions in template rendering, I will try to find a solution. |
ya, due to the nature of certain functions this might not be a workable solution, unless for the first pass you overrode what the template functions do with mocks. |
@mumoshu I resolved errors and side-effects happening on the initial render. Also,
is resolved. You can see this in main_test.go |
Thanks @davidovich. It looks awesome! One nit I found is that whether you should also stub Not sure what's the less confusing way yet. |
My overall concern is all of the edge cases this might bring up and any confusion it might cause people with how helmfile works. If everyone is comfortable with those things then I'm ok. |
@mumoshu I am not sure I understand what you mean. Note that if the prerender fails at all, it falls back to an empty |
@davidovich Hey! I took sometime to review it again, and noticed that you're testing the opposite of the issue I found. It was that, the template execution fails when you had no values set in You'll probably want to define a |
You are correct, this fails, but wouldn't it fail even if we didn't have a double render ? Is the concern related to less obvious failure mode ? I have added an |
@davidovich Thanks for your continuous effort!
Yeah, I agree. To provide you more context, @sstarcher and I had also concluded so #317. Does that sound good to you, too? |
Oops. In the context of double rendering, I suppose, this should be "set Otherwise the first render against a helmfile that contains something like |
@mumoshu I have implemented the I came back to this comment:
and added a test to see the behavior. The current code as you wrote it supports nicely this usecase. If you have a .gotmpl file, all render functions are upheld and allow you to use readFile and exec in the environment section ! I think this is aligned with your expectations, and it makes a lot of sense. |
Tell me if everything is ok, and I will rebase on master. |
I tested this off your branch and I had no issue with the double rendering. I'm having another issue with helmfile, but I don't think it's related to your rendering. my rending in a helmfile is very simple so I'm confident your implementation will work for me. |
This allows using the values defined in the environments: section. This is done by using a buffer instead of re-reading the file twice.
394b48d
to
7375ce2
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 👍
I know there are still some concerns. But let's keep the ball rolling. @davidovich has done an awesome job that this is indeed working!
Thanks again for your contribution 🎉
This resolves #297 |
if c.preRender { | ||
tmpl.Option("missingkey=zero") | ||
} else { | ||
tmpl.Option("missingkey=error") |
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.
This seems to resolve #317, too.
This allows using the values defined in the environments: section.
This is done by using a buffer instead of re-reading the file twice.
see #254
@mumoshu can you weigh in on the approach ?