Helm: --set analyse uniquement les valeurs numériques comme float64

Créé le 17 déc. 2016  ·  68Commentaires  ·  Source: helm/helm

Je viens de remarquer que quelque chose comme helm install --set tag=20161216 se termine en notation scientifique dans le modèle et c'est parce que {{ typeOf .Value.tag }} donne float64 .

C'est même vrai pour les petits entiers comme helm install --set tag=1 -> float64 .

Cela se produit avec helm 2.1.0

help wanted

Commentaire le plus utile

Rétrocompatibilité? D'une fonctionnalité qui est tout simplement «WTF» et que peu de gens veulent ou utilisent? Dans un outil en plein développement et pas vraiment adopté à grande échelle? Je suggère de repenser cela et de le réparer avant qu'il ne soit vraiment tard.

Tous les 68 commentaires

Cela fonctionne-t-il différemment si vous faites --set tag=\"1\" ?

Grâce à @chancez, nous connaissons le problème exact: lors des conversions vers et depuis JSON effectuées par ghodss/yaml , des entiers sont convertis en float64s pour représenter le type numérique de Javascript. Cela provoque la représentation de tous les nombres entiers au-dessus d'une certaine valeur en notation scientifique.

J'ai été mordu par le même problème. La façon de surmonter la bosse (ou le bogue) est de faire ceci:

--set bignumber=\\"a185576882739235744\\"

Une autre solution de contournement que nous avons utilisée est de faire des choses comme ceci:

--set port=":1234567"

Puis dans le modèle:

{{ .Values.port | replace ":" "" }}

Beurk! 😷

C'est une sacrée douleur, et la solution de contournement de

Je ne suis pas encore tout à fait disposé à avaler ma fierté et à essayer le vilain hack de @technosophos ...

Pour l'instant, je pirate autour de cela en développant mon script de déploiement pour écrire les données en tant que yaml dans un fichier temporaire et l'utiliser comme argument -f .

Je rencontre le même problème de temps en temps pour la balise d'image.
Je vais essayer d'utiliser l'une de ces solutions de contournement. J'espère que cela sera corrigé bientôt :)

Dans mon cas, voir ceci ci-dessous sur --set image.tag=5997578 :

$ kubetctl describe po msj-treasure-map-msj-treasure-map-192172122-dnb80
...
Events:
  Type     Reason         Age               From                                    Message
  ----     ------         ----              ----                                    -------
  Normal   Scheduled      1m                default-scheduler                       Successfully assigned msj-treasure-map-msj-treasure-map-192172122-dnb80 to ip-10-253-13-113.ec2.internal
  Warning  InspectFailed  15s (x9 over 1m)  kubelet, ip-10-253-13-113.ec2.internal  Failed to apply default image tag "596297932419.dkr.ecr.us-east-1.amazonaws.com/msj-trmap-uwsgi:5.997578e+06": couldn't parse image reference "596297932419.dkr.ecr.us-east-1.amazonaws.com/msj-trmap-uwsgi:5.997578e+06": invalid reference format
  Warning  InspectFailed  15s (x9 over 1m)  kubelet, ip-10-253-13-113.ec2.internal  Failed to apply default image tag "596297932419.dkr.ecr.us-east-1.amazonaws.com/msj-trmap-nginx:5.997578e+06": couldn't parse image reference "596297932419.dkr.ecr.us-east-1.amazonaws.com/msj-trmap-nginx:5.997578e+06": invalid reference format
  Warning  FailedSync     15s (x9 over 1m)  kubelet, ip-10-253-13-113.ec2.internal  Error syncing pod, skipping: [failed to "StartContainer" for "msj-treasure-map-uwsgi" with InvalidImageName: "Failed to apply default image tag \"596297932419.dkr.ecr.us-east-1.amazonaws.com/msj-trmap-uwsgi:5.997578e+06\": couldn't parse image reference \"596297932419.dkr.ecr.us-east-1.amazonaws.com/msj-trmap-uwsgi:5.997578e+06\": invalid reference format"
, failed to "StartContainer" for "msj-treasure-map-nginx" with InvalidImageName: "Failed to apply default image tag \"596297932419.dkr.ecr.us-east-1.amazonaws.com/msj-trmap-nginx:5.997578e+06\": couldn't parse image reference \"596297932419.dkr.ecr.us-east-1.amazonaws.com/msj-trmap-nginx:5.997578e+06\": invalid reference format"
$ helm version                                                                                                                                                                             
Client: &version.Version{SemVer:"v2.5.1", GitCommit:"7cf31e8d9a026287041bae077b09165be247ae66", GitTreeState:"clean"}
Server: &version.Version{SemVer:"v2.5.1", GitCommit:"7cf31e8d9a026287041bae077b09165be247ae66", GitTreeState:"clean"}

Je rencontre également le même problème sur la barre 2.6.2.

Client: &version.Version{SemVer:"v2.6.2", GitCommit:"be3ae4ea91b2960be98c07e8f73754e67e87963c", GitTreeState:"clean"}
Server: &version.Version{SemVer:"v2.6.2", GitCommit:"be3ae4ea91b2960be98c07e8f73754e67e87963c", GitTreeState:"clean"}
  • 1

La suppression de YAML en JSON supprime beaucoup d'informations, la plupart liées au type. Cela signifie que vous ne pouvez pas saisir les valeurs de contrôle avant le déploiement.

Je suppose que cela peut être résolu en déplaçant vers une autre bibliothèque yaml. Peut-être celui-ci: https://github.com/go-yaml

En luttant avec ce problème aujourd'hui, j'ai découvert que le filtre toString peut vous aider:

dockerPort: {{ .Values.dockerPort | toString }}

Ensuite, j'ai pu passer le port en ligne de commande ( --set dockerPort=2376 ) et le faire interpréter correctement.

Nous venons de voir cela sur 2.7.2 et la plupart des solutions de contournement ne fonctionnent pas vraiment pour nous, sauf écrire toutes les options --set dans un fichier local et les transmettre via helm -f locals.yml .

J'ai également vu cela dans 2.7.2 (et déposé # 3246 en conséquence), donc +1 sur cette question. Comme dans https://github.com/kubernetes/helm/issues/3001 , j'utilisais également les SHA git pour mes balises d'image docker. Ma solution de contournement pour l'instant, FWIW, est de suffixer les balises d'image avec -gitsha

+1 pour moi aussi.

$ helm version                                                                                                                                    ⏎
Client: &version.Version{SemVer:"v2.7.2", GitCommit:"8478fb4fc723885b155c924d1c8c410b7a9444e6", GitTreeState:"clean"}
Server: &version.Version{SemVer:"v2.7.2", GitCommit:"8478fb4fc723885b155c924d1c8c410b7a9444e6", GitTreeState:"clean"}

$ git rev-parse --short HEAD
6180689

$ helm upgrade foobar \
    -i charts/foobar \
    --set image.tag=$(git rev-parse --short HEAD) \
    --reuse-values

Après le déploiement, j'obtiens ceci:

Failed to apply default image tag "gcr.io/foobar/foobar:6.180689e+06": couldn't parse image reference "gcr.io/foobar/foobar:6.180689e+06": invalid reference format
Error syncing pod

J'obtiens également InvalidImageName lors de l'exécution de kubectl get pods .

L'ajout de | toString ne semble pas faire de différence pour moi.

pouvez-vous simplement faire:

{{ .Values.tag | int64 }}

@laverite dans les graphiques absolument, mais cela utilise l'analyseur --set. Ce problème n'existe que pour l'analyseur --set. les valeurs transmises via values.yaml sont analysées correctement. :)

Il semble que cela soit lié au # 3155

oui, croyez-le @jesselang

Même problème ici avec helm 2.8.0.

@bacongobbler ou @technosophos J'ai un correctif pour ce problème sur # 3599, il y a déjà une approbation, il en faut juste une autre. Merci!

résolu via # 3599

merci pour le ping @ arturo-c :)

Voir aussi ce bug avec Helm 2.9.1

Je me demande pourquoi helm lint ne comprend pas ça? Voir # 4099

Je suis curieux de savoir pourquoi cela a été résolu en ajoutant --set-string , au lieu de corriger ce qui me semble être un bug évident dans --set .

Est-il probable que quelqu'un ait l'intention de forcer les nombres à utiliser la notation scientifique dans leurs fichiers yaml?

deux mots: rétrocompatibilité :)

Nous pouvons changer la façon dont l' analyseur --set contraint les valeurs entières dans Helm 3, mais de manière générale, nous avons choisi d'empêcher de changer le comportement attendu des fonctionnalités de base comme --set car il y a tellement d'utilisateurs exécutant Helm en production. Nous ne pouvons pas non plus forcer toutes les valeurs de --set à des chaînes car cela brisera le comportement existant tel que le comportement attendu autour des valeurs nulles et véridiques dans les fichiers de valeurs, donc --set-string été accepté comme réalisable solution pour le moment.

Rétrocompatibilité? D'une fonctionnalité qui est tout simplement «WTF» et que peu de gens veulent ou utilisent? Dans un outil en plein développement et pas vraiment adopté à grande échelle? Je suggère de repenser cela et de le réparer avant qu'il ne soit vraiment tard.

@technosophos merci.
Exemple:

kind: Secret
data:
  some_db_port: {{ .Values.dbInfo.db_port | replace ":" "" | b64enc }}

c'est du travail pour moi.

@OndraZizka merci pour les commentaires (très passionnés). Nous cherchons définitivement à résoudre certains de ces problèmes de comportement loufoques que l'analyseur --set a pour Helm 3, probablement en le remplaçant par quelque chose de similaire au nouvel analyseur --set-string .

Je suis tout à fait d'accord que le comportement de --set est très étrange dans ce cas (et même carrément faux), mais nous ne pouvons pas nous attendre à remplacer une bibliothèque d'analyse entière par une autre et être convaincus qu'il n'y aura pas d'autre coercition bogues dans le nouveau système. L'échange de bibliothèques de coercition serait considéré comme une modification rétrocompatible.

Pour le moment, --set-string est une excellente fonctionnalité et je le recommande vivement à quiconque rencontre ce bogue d'utiliser autant que possible --set-string lorsque vous ne comptez pas sur la coercition de type. De cette façon, les valeurs sont forcées d'être forcées en tant que chaîne et non en tant que flottant.

Malheureusement, quand Ansible formate un dict en yaml (qui est mon values.yaml), il n'ajoute pas de guillemets, ce qui est un gros problème pour moi. Je n'arrive pas à croire que je doive utiliser ce putain de hack: replace ":" ""

si vous avez besoin d'une solution qui fonctionne sans préfixer la balise avec un : et la supprimer plus tard, vous pouvez utiliser celle-ci (tl; dr: lorsque la balise est un nombre, utilisez printf pour l'imprimer, sinon imprimez le chaîne que vous avez)

{{- $tag :=  .Values.image.tag }}
{{- $type := printf "%T" $tag }}
image: "{{ .Values.image.repository }}:{{if eq $type "float64"}}{{ printf "%.0f" $tag }}{{ else }}{{ $tag }}{{ end }}"

Le bogue se produit également avec helm ... -f myval.yaml

Pour info, cela a été corrigé dans https://github.com/helm/helm/pull/6010.

@bacongobbler se passe toujours sur moi avec la version de barre v2.14.3

Pouvez-vous ouvrir un nouveau numéro? Merci.

réouverture en raison de la nécessité de revenir au n ° 6010 dans le n ° 6749.

Un ETA quand le correctif serait disponible?

voir # 6888.

@sagarkal pour nous assurer que nous sommes sur la même onde : le correctif susmentionné vise uniquement à atteindre Helm v3, pas v2 (je déclare cela comme un contributeur aléatoire, la décision réelle appartient toujours à l'équipe). Le changement est relativement massif et ne devrait pas être considéré comme sûr à 100% pour être fusionné dans la branche 2.x, qui est désormais uniquement patch. En attendant, si vous avez une chance, ce serait formidable si vous pouviez tester la branche PR par rapport à votre cas d'utilisation et nous faire savoir si les choses fonctionnent comme prévu. Cela aiderait beaucoup!

Utiliser --set-string image.tag=6599236 fonctionné pour moi avec un modèle simple comme celui-ci

  ...
      containers:
        - name: {{ .Chart.Name }}
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
          env:
  ...

Se heurter à cela avec une grande valeur entière spécifiée dans le fichier de valeurs du graphique. Il est implicitement converti en flotteur avec une notation scientifique. Le simple fait de convertir la valeur en int corrigé ce problème, et semble beaucoup plus propre que certaines des autres solutions de contournement que j'ai vues:

# values.yaml

tomcat:
  maxPostSize: 2097152
# Cast to int when used

{{ .Values.tomcat.maxPostSize | int }}

Cela a été testé avec Helm v3.1.1.

C'est bon à savoir! C'est certainement une solution de contournement facile par rapport à beaucoup de ceux que j'ai vus. Merci!

@Rathgore Casting vers un int est parfait pour traiter les entiers tout le temps, mais dans mon cas, la valeur d'entrée doit être traitée comme une chaîne mais se présente sous la forme de chiffres (parfois). Par exemple, le hachage de validation github raccourci de 7 longueurs, parfois c'est une chaîne et parfois c'est juste une chaîne de chiffres. Dans ce cas, la transmission de la valeur avec l'option --set-string fonctionne à chaque fois.

@ m0rganic Je n'ai pas testé cela, mais vous pouvez essayer d'utiliser toString au lieu de int ou de définir explicitement le type en utilisant !!str . Ce n'est pas nécessaire si vous utilisez simplement --set-string mais nous avons également besoin de ce comportement pour les valeurs définies dans le graphique.

@ m0rganic Je n'ai pas testé cela, mais vous pouvez essayer d'utiliser toString au lieu de int ou de définir explicitement le type en utilisant !!str . Ce n'est pas nécessaire si vous utilisez simplement --set-string mais nous avons également besoin de ce comportement pour les valeurs définies dans le graphique.

toString ne fonctionne pas, et dans certains cas, je ne pourrais pas utiliser !!str .

Existe-t-il un plan pour corriger ce problème? Ce numéro est ouvert depuis un certain temps ...

Voir # 6888. Sinon, non. Nous avons documenté de nombreux modèles à utiliser. Mais nous n'avons pas trouvé de solution qui résout plus de problèmes qu'elle n'en cause. N'hésitez pas à vous essayer à un PR.

Merci pour la réponse rapide! Je ne suis pas certain qu'aucune des solutions de contournement proposées ne résout mon cas d'utilisation, mais je vais réessayer.

Cela fonctionne-t-il différemment si vous faites --set tag=\"1\" ?

dans mon cas, j'ai utilisé "" dans les valeurs int, float et bool et cela a fonctionné, merci

Sur la base de ce commentaire , il peut sembler que ce n'est plus un problème pour Helm 3, juste pour Helm 2. J'aimerais savoir qui rencontre toujours ce problème, comment et avec quelles versions de Helm.

Pour les utilisateurs de Helm 2, nous n'acceptons que les correctifs de sécurité pour le moment, nous ne chercherons donc pas à corriger ce bogue pour Helm 2. Cependant, si cela est toujours pertinent pour Helm 3, j'apprécierais plus d'informations de la communauté sur ce bug particulier.

pour helm 2, vous pouvez lancer ce que vous voulez entre le () comme dans l'exemple ci-dessous

{{- range $i := until (int .Values.deployment.numberofracks) }}
  - name: rack{{$i}}
{{- end}}

Je vais supposer que cela a été corrigé pour Helm 3, car cela fait 3 semaines depuis ma dernière publication que cela semble avoir été corrigé. Si d'autres personnes rencontrent encore ce problème avec Helm 3, n'hésitez pas à en discuter et nous pourrons rouvrir ce problème. Merci!

C'est toujours un problème; Je suis sur 3.3.0 et je rencontre toujours ce problème.

Pouvez-vous s'il vous plaît fournir une démonstration?

Heureux, mais je ne sais pas vraiment comment faire cela; J'ai un graphique qui a dans son values.yaml un champ qui ressemble à ceci:

customEnv:
  SOME_ENV_VAR: 10000000

puis dans templates/deployment.yaml , j'ai ceci:

    ...
    containers:
      - name: someContainer
        env:
           {{- range $key, $value := .Values.customEnv }}
            - name: {{ $key | quote }}
              value: {{ $value | quote }}
          {{- end }}
    ...

Quand j'exécute helm template , j'obtiens cette valeur dans la sortie rendue:

    ...
    containers:
      - name: someContainer
        env:
            - name: "SOME_ENV"
              value: "1e+07"
   ...

puis mon application déployée échoue lorsqu'elle tente d'analyser la valeur de SOME_ENV comme un nombre.

D'accord. J'ai réussi à reproduire le même problème en suivant vos instructions avec Helm 3.3.1. Merci. Réouverture.

Je rencontre le même problème sous un angle légèrement différent. Mon appVersion est 8482e77 , si je référence appVersion partout où il est rendu comme +Inf . C'est amusant de déboguer BTW.

Éditer:
changer appVersion de appVersion: 8482e77 à appVersion: "8482e77" résolu mon problème

C'est à prévoir. Sans guillemets, YAML analyse cette valeur en tant que notation scientifique (comme 8482e77 signifie «8482 * 10 ^ 77»). Si vous souhaitez qu'une valeur soit traitée comme une chaîne, placez-la entre guillemets.

J'ai eu ce problème avec la balise d'image contianer. Le problème a été résolu en créant l'assistant ci-dessous:

+{{/* Generate Image Name */}}
+{{- define "helpers.image" }}
+{{- $tag := printf "%f" .Values.app.image.tag -}} 
+{{- if regexMatch "^[0-9]+\\.[0-9]+$" $tag }}
+{{ .Values.image.repository }}:{{ .Values.image.tag | int }}
+{{- else }}
+{{ .Values.image.repository }}:{{ .Values.image.tag }}
+{{- end }}
+{{- end }}

Et puis, au manifeste de déploiement:

   containers:
       - name: {{ template "helpers.fullname" . }}
         image: {{ template "helpers.image" . }}

ce problème est-il résolu? sinon, je voudrais résoudre ce problème.

Non, voir ci-dessus . Assurez-vous de lire le fil de discussion et de tester par vous-même. :)

Ce problème a été marqué comme obsolète, car il est ouvert depuis 90 jours sans activité. Ce fil sera automatiquement fermé dans 30 jours si aucune autre activité ne se produit.

bosse, toujours un problème

J'utilise cette solution de contournement lorsque je rencontre ce problème sur les identifiants de validation peut-être numériques:

{{- define "numericSafe" -}}
{{- if . | toString | contains "e+" -}}
{{ . | toString | replace "." "" | regexFind "^\\d+" }}
{{- else -}}
{{ . }}
{{- end -}}
{{- end -}}

puis utilisez avec

{{ include "numericSafe" .Values.git.commitID }}

Cela résout les problèmes si votre chaîne d'origine ne contient jamais de point et e+ , bien que je ne sache pas si c'est une chaîne de nombres très longue, quelque chose sera omis.

@urakagi malheureusement, cela ne fonctionne pas si votre valeur est: 1800000

Un correctif est-il prévu pour ce problème?

Les mises à jour?

@bacongobbler la repro de @edobry est en fait un problème différent. Celui-ci concernait à l'origine des valeurs transmises avec --set , ce qui a maintenant été corrigé et l'option --set-string été ajoutée.

La repro concerne un nombre à l'intérieur de values.yaml étant changé en notation scientifique. La repro peut être corrigée en citant le nombre en values.yaml , si elle doit être traitée comme une chaîne. S'il est utilisé comme un nombre, les notations ne devraient pas poser de problème.

J'ai regardé dans le code et je pense que je pourrais changer le comportement pour produire des nombres en notation standard au lieu de 20 nombres décimaux. Après cela, il semble y avoir une limite d'implémentation dans l'analyseur yaml sous-jacent qui arrondit les très grands nombres et / ou les transforme en notation scientifique.

J'ai également essayé de trouver un autre problème qui résoudrait le problème tel que décrit dans la repro de

Ainsi, lorsque quelqu'un utilise par exemple des balises numériques, qui n'ont aucune valeur numérique (aucune arithmétique n'est définie sur elles), elles doivent être entre guillemets values.yaml pour être traitées comme des chaînes et cela devrait résoudre le problème:

# values.yaml
foo: "10000000"
# template
foo: {{ .Values.foo | quote }}



md5-aba98a385ca8fe457cb1f98967ed3bf1



# Source: foo/templates/x.yaml
foo: "10000000"



md5-265ed31678f08bdbd76c259b974f5398



# Source: foo/templates/x.yaml
foo: "1e+07"



md5-3df6a1bc5fe8f474ded5c2033aaf11a3



# Source: foo/templates/x.yaml
foo: "10000000"

Par conséquent, je pense que cela peut être fermé et qu'un nouveau problème peut être ouvert si quelqu'un pense que l'analyse des nombres non cotés devrait suivre d'autres règles que ce qu'elle fait déjà.

Cette page vous a été utile?
0 / 5 - 0 notes