Siga esta edição # 1055
tentando fazer o mesmo, pense com:
{{ range $k, $v := until (atoi (quote .Values.Replicas) | default 5) }}
apiVersion: v1
kind: Service
metadata:
name: zookeeper-{{$v}}
namespace: {{ .Values.Namespace }}
labels:
node: "zookeeper-{{$v}}"
annotations:
"helm.sh/created": {{ .Release.Time.Seconds | quote }}
service.alpha.kubernetes.io/tolerate-unready-endpoints: "true"
spec:
ports:
- port: {{.Values.PeerPort}}
name: peer
- port: {{.Values.LeaderElectionPort}}
name: leader-election
- port: {{.Values.ClientPort}}
name: client
selector:
component: "{{.Release.Name}}-{{.Values.Component}}"
zookeepernode: "zookeeper-{{$v}}"
{{ end }}
Mas eu recebo este erro:
Error: render error in "zookeeper/templates/deployment.yaml": template: zookeeper/templates/deployment.yaml:6:22: executing "zookeeper/templates/deployment.yaml" at <.Values.global.names...>: can't evaluate field Values in type int
Posso esquecer alguma coisa, alguma ideia?
finalmente encontro um truque, mas pode ser algo que possamos melhorar.
{{- $root := . -}}
{{ range $k, $v := until (atoi (quote .Values.Replicas) | default 5) }}
apiVersion: v1
kind: Service
metadata:
name: zookeeper-{{$v}}
namespace: {{ $root.Values.Namespace }}
labels:
node: "zookeeper-{{$v}}"
annotations:
"helm.sh/created": {{ $root.Release.Time.Seconds | quote }}
service.alpha.kubernetes.io/tolerate-unready-endpoints: "true"
spec:
ports:
- port: {{$root.Values.PeerPort}}
name: peer
- port: {{$root.Values.LeaderElectionPort}}
name: leader-election
- port: {{$root.Values.ClientPort}}
name: client
selector:
component: "{{$root.Release.Name}}-{{$root.Values.Component}}"
zookeepernode: "zookeeper-{{$v}}"
{{ end }}
Oh, sim ... essa é uma das coisas mais esotéricas sobre os modelos Go. O escopo .
é substituído em uma estrutura de controle.
Tentei algumas maneiras de contornar isso, mas a melhor é a solução do exemplo acima. Marcando como fechado.
Isso também me incomodou :(
@technosophos Talvez você possa considerar mudar esse comportamento? ou seja, desative a iteração com intervalo sem atribuir variáveis explicitamente e preserve o escopo
Isso é algo que o Go executa como parte do texto / modelo, portanto, não há nada acionável diretamente no Helm. O escopo é alterado ao iterar por meio de uma estrutura de controle como range
. Sua melhor aposta para mudar esse comportamento seria registrar um bug upstream com o próprio Go.
documentos relevantes de texto / modelo :
{{range pipeline}} T1 {{end}}
O valor do pipeline deve ser uma matriz, fatia, mapa ou canal. Se o valor do pipeline tiver comprimento zero, nada será gerado; caso contrário, o ponto é definido para os elementos sucessivos da matriz, fatia ou mapa e T1 é executado . Se o valor for um mapa e as chaves forem do tipo básico com uma ordem definida ("comparável"), os elementos serão visitados em uma ordem de chave classificada.
Por alguma razão, a solução alternativa $root
pareceu funcionar para mim momentaneamente, mas agora está sufocando:
Error: UPGRADE FAILED: unable to recognize "": no matches for /, Kind=Deployment
Não trabalhei no projeto por um tempo. Não tenho ideia do que mudou no meio. Remover a atribuição $root
elimina esse erro.
Ok, então começou a funcionar novamente quando removi um dos -
resultando em {{- $root := . }}
. Provavelmente estou entendendo mal alguma coisa.
Edit : Portanto, algum texto relevante da documentação do modelo Go é:
No entanto, para ajudar na formatação do código-fonte do modelo, se o delimitador esquerdo de uma ação (por padrão "{{") for seguido imediatamente por um sinal de menos e um caractere de espaço ASCII ("{{-"), todos os espaços em branco à direita são cortados do texto imediatamente anterior. Da mesma forma, se o delimitador direito ("}}") for precedido por um espaço e um sinal de menos ("-}}"), todos os espaços em branco à esquerda são cortados do texto imediatamente seguinte. Nesses marcadores de corte, o espaço ASCII deve estar presente; "{{-3}}" analisa como uma ação contendo o número -3.
Edit2 : Isso está ficando cada vez mais estranho. Se eu adicionar uma instrução printf imediatamente após a atribuição de raiz, ela funcionará novamente. Suspiro, o que quer que funcione, eu acho.
# We assign the current context to a variable to access it in range iteration below
{{- $self := . -}}
{{ printf "%#v" $ }}
(Na verdade estou usando self como o parâmetro de atribuição em vez de root)
Além disso, não funciona sem adicionar um comentário inicial ao documento.
@worldsayshi Para valer a pena, acabei de encontrar o mesmo problema e descobri que há uma documentação relevante da seção de variáveis :
However, there is one variable that is always global - $ - this variable will always point to the root context. This can be very useful when you are looping in a range need to know the chart’s release name.
Acontece que é mais simples fazer algo assim se você precisar acessar o contexto raiz de um bloco range
:
{{- range $key, $value := .Values.someHash }}
{{ $key }}: {{ print $.Values.prefix ":" $value | quote }}
{{- end }}
Se alguém está vindo aqui tão confuso quanto eu sobre como aplicar a solução elegante de @DeviateFish para funções de modelo (como aquelas que você obtém gratuitamente em helm create
), você só precisa passar o contexto adequado para o função de modelo.
{{ range tuple "fizz" "buzz" }}
...
{{ template "foobar.fullname" $ }} # Worky.
{{ template "foobar.fullname" . }} # No worky.
...
{{ end }}
Bom modelo de @killix ... uma coisa que me levou algumas tentativas para localizar foi que o exemplo no início deste tópico deve ter um ---
no final do modelo para separar os serviços criados no ciclo. Espero que isso economize alguns minutos de depuração para outra pessoa.
Tenho alguns problemas com este escopo e recebo o erro - Erro: FALHA NO ATUALIZAÇÃO: template: maas360 / charts / consumer / templates / _consumer. tpl: 84 : 33: executando "loadconsumerConfigFiles" em: ponteiro nulo avaliando interface {} .Glob.
Eu tenho meu configmap.yaml que chama um modelo conforme abaixo -
{{- $ root: =. -}}
{{intervalo $ instance_id, $ value: = .Values.instance_names}}
apiVersion: v1
tipo: ConfigMap
metadados:
nome: {{$ .Release.Name}} - {{$ .Values.maasappname}} - {{$ instance_id}} - configmap
dados:
{{fim}}
E eu tenho este loadconsumerConfigFiles no arquivo de modelo -
{{- define "loadconsumerConfigFiles" -}}
{{- $ root: =. -}}
{{- $ arg1: = índice. "0" -}}
{{- $ arquivo: = .Arquivos}}
{{- intervalo $ caminho, $ byte: = $ root.Files.Glob "config / *"}}
Eu recebo este erro. Basicamente, estou tentando passar instance_id como um parâmetro para loadconsumerConfigFiles para que eu possa usar isso dentro desse modelo. Você poderia ajudar o que estou perdendo. Já passei esse contexto raiz. ainda está mostrando o erro.
Isso funcionou para mim redefinir o escopo de volta à raiz e preservar o item sobre o qual estou iterando. Isso teve a vantagem de contornar um bug no IntelliJ onde não foi possível encontrar a definição de variáveis que fazem referência a $root
{{- range .Values.deployments }}
{{- $rangeItem := . -}}
{{- with $ }}
---
apiVersion: apps/v1
kind: Deployment
name: {{ $rangeItem.name }}
labels:
- organization: {{ .Values.organization }}
# etc etc
...
{{- end }}
{{- end }}
ok, muito obrigado.
Comentários muito úteis
@worldsayshi Para valer a pena, acabei de encontrar o mesmo problema e descobri que há uma documentação relevante da seção de variáveis :
However, there is one variable that is always global - $ - this variable will always point to the root context. This can be very useful when you are looping in a range need to know the chart’s release name.
Acontece que é mais simples fazer algo assim se você precisar acessar o contexto raiz de um bloco
range
: