Helm自定义模板读取外部文件报错,直接读取正常求助
问题排查:Helm模板自定义readfile调用.Files.Get报错的原因及解决方法
问题场景
为动态读取外部文件内容到ConfigMap,在templates/_helpers.tpl中定义readfile模板:
{{- define "readfile" -}} {{- $content := .Files.Get .metrics -}} {{ $content }} {{- end -}}
在templates/configMap.yaml中调用该模板:
fileContent_via_template: {{ include "readfile" (dict "metrics" "panels/pods/memory.txt") }}
外部文件panels/pods/memory.txt内容:
This is dummy content which is displayed from memory.txt file
此时触发报错:
Error: template: grafana/templates/configMap.yaml:2:22: executing "grafana/templates/configMap.yaml" at <include "readfile" (dict "metrics" "panels/pods/memory.txt")>: error calling include: template: grafana/templates/_helpers.tpl:42:24: executing "readfile" at <.Files.Get>: nil pointer evaluating interface {}.Get
但直接在ConfigMap中调用.Files.Get可正常获取内容:
fileContent: {{ .Files.Get "panels/pods/memory.txt" }}
输出结果:
--- # Source: grafana/templates/configMap.yaml fileContent: This is dummy content which is displayed from memory.txt file
原因分析
报错核心是:调用readfile模板时传入的是自定义dict对象,该对象仅包含metrics字段,不存在Helm顶层上下文的.Files对象。模板中尝试访问.Files.Get时,当前上下文(传入的dict)无Files属性,因此触发nil指针错误。
直接调用.Files.Get时,当前上下文是Helm根对象,自带Files等内置对象,所以能正常读取文件。
解决方法
方法1:将顶层.Files传入自定义dict
修改ConfigMap中的调用代码,把根上下文的.Files对象加入传入的dict:
fileContent_via_template: {{ include "readfile" (dict "metrics" "panels/pods/memory.txt" "Files" .Files) }}
templates/_helpers.tpl中的模板无需修改,此时模板内的.Files就是传入的顶层Files对象,可正常调用.Get方法。
方法2:合并自定义参数与顶层上下文
使用merge函数将自定义dict与顶层上下文合并,让模板同时拥有自定义参数和Helm内置对象:
fileContent_via_template: {{ include "readfile" (merge (dict "metrics" "panels/pods/memory.txt") .) }}
这种方式下,模板内的.metrics可访问自定义参数,.Files也能访问顶层的Files对象,无需修改模板代码。
内容的提问来源于stack exchange,提问作者Ashish Kumar
相关产品推荐
相关产品推荐

