web-dev-qa-db-fra.com

Remplacement des attributs dans la recette

Disons que j'ai un attribut par défaut dans un livre de recettes:

default.nginx_upstreams = {
    'service1' => ['service1.server.com'],
    'service2' => ['service2.server.com'],
}

Ensuite, il est modifié et remplacé dans les rôles et les environnements jusqu'à ce qu'il arrive enfin à ma recette. Là, je calcule quelques services supplémentaires que je voudrais ajouter à l'attribut. Si je fais quelque chose comme ça:

node.nginx_upstreams.merge! {'service3' => ['service3.server.com']}

puis quand j'essaie d'utiliser l'attribut dans mon modèle, j'obtiens un undefined method 'each' for nil:NilClass dans mon modèle quand j'essaye de faire

<% node.nginx_upstreams.each do |name, servers| %>

De plus, je reçois également un WARN: Setting attributes without specifying a precedence is deprecated and will be removed in Chef 11.0. L'avertissement utile m'indique comment définir les attributs à la priorité normale (apparemment, en utilisant node.set["key"] = "value", Mais ne me dit pas comment spécifier les attributs par défaut ou les remplacer.

Je peux contourner ce problème en faisant quelque chose comme ceci:

upstreams = node.nginx_upstreams.to_hash
upstreams.merge! {'service3' => ['service3.server.com']}

template "nginx_config" do
    variables({:upstreams=>upstreams})
end

mais cela ressemble à un hack. Je ne trouve aucune documentation sur node.set() au-delà de cette page , ce qui indique également que vous pouvez définir à la fois des attributs normaux et de remplacement dans la recette mais ne dit pas comment.

Alors ... comment définissez-vous correctement les attributs (qui sont fusionnés en profondeur avec tout le reste) de l'intérieur de la recette? Que fait réellement l'appel node.set() et puis-je lui indiquer la priorité à laquelle je souhaite fusionner?

38
Igor Serebryany

default.nginx_upstreams est le même que default[:nginx_upstreams] et default['nginx_upstreams'] - la convention est d'utiliser 1 des deux derniers. Et comme vous utilisez davantage les chaînes, utilisez-les ici aussi.

La façon dont vous initiez nginx_upstreams dans le fichier d'attributs revient à le faire de cette façon:

default['nginx_upstreams']['service1'] = ['service1.server.com']
default['nginx_upstreams']['service2'] = ['service2.server.com']

Et vous n'avez pas besoin d'initier default['nginx_upstreams'] = {} avant ça. Ce ne sont pas des hachages, mais des attributs, et ils sont beaucoup plus intelligents. :)

La modification des attributs depuis l'intérieur de la recette se fait comme ça:

node.default['nginx_upstreams']['service3'] = ['service3.server.com']

Vous pouvez utiliser set ou override au lieu de default ici, si vous devez modifier la priorité. Omettre le nom de priorité (node['nginx_upstreams'] ou node.nginx_upstreams) utilisera la priorité set. Mais cela est obsolète et sera bientôt supprimé - c'est de cela qu'il s'agit. Consultez la page de manuel sur les attributs , car tout est réellement là.

44
Draco Ater

Je voulais simplement donner un aperçu des attributs Chef, il est très important pour les utilisateurs, qui vont renvoyer cette question sur le remplacement des attributs de nœud.

Les méthodes de fichier correspondent aux attributs

Utilisez les méthodes suivantes dans le fichier d'attributs d'un livre de recettes ou dans une recette. Ces méthodes correspondent au type d'attribut du même nom:

  • passer outre
  • default
  • normal (ou set, où set est un alias pour normal)
  • _sauf si
  • attribut?

Priorité des attributs

Les attributs sont toujours appliqués par le chef-client dans l'ordre suivant:

  1. Un attribut par défaut situé dans un fichier d'attributs de livre de recettes
  2. Un attribut par défaut situé dans une recette
  3. Un attribut par défaut situé dans un environnement
  4. Un attribut par défaut situé dans le rôle
  5. Un attribut force_default situé dans un fichier d'attributs de livre de recettes
  6. Un attribut force_default situé dans une recette
  7. Un attribut normal situé dans un fichier d'attributs de livre de recettes
  8. Un attribut normal situé dans une recette
  9. Un attribut de remplacement situé dans un fichier d'attributs de livre de recettes
  10. Un attribut de remplacement situé dans une recette
  11. Un attribut de remplacement situé dans un rôle
  12. Un attribut de remplacement situé dans un environnement
  13. Un attribut force_override situé dans un fichier d'attributs de livre de recettes
  14. Un attribut force_override situé dans une recette
  15. Un attribut automatique identifié par Ohai au début de l'exécution chef-client

où le dernier attribut de la liste est celui qui est appliqué au nœud.

Cela signifie que l'attribut OHAI aura la priorité la plus élevée, alors que l'attribut par défaut dans le fichier d'attribut du livre de cuisine aura la priorité la plus faible.

Remarque: fourni les détails importants des documents de Chef pour attributs pour le bénéfice des utilisateurs. Parce que parfois l'URL sera déplacée ou invalide.

10
Saravanan G

Donc, après avoir fouillé, j'ai trouvé la réponse:

node.set
Utilisation node.default (ou peut-être node.override) au lieu de node.set car node.set est un alias pour node.normal. Les données normales sont conservées sur l'objet nœud. Par conséquent, l'utilisation de node.set conservera les données dans l'objet nœud. Si le code qui utilise node.set est supprimé ultérieurement, si ces données ont déjà été définies sur le nœud, elles le resteront.

Les attributs normaux et de substitution sont effacés au début de l'exécution chef-client, puis sont reconstruits dans le cadre de l'exécution en fonction du code des livres de recettes et des recettes à ce moment-là.

node.set (et node.normal) ne doit être utilisé que pour générer un mot de passe pour une base de données lors de la première exécution chef-client, après quoi il est mémorisé (au lieu de persister). Même ce cas doit être évité, car l'utilisation d'un sac de données est la méthode recommandée pour stocker ce type de données.

4
AngryChef