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?
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à.
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:
Priorité des attributs
Les attributs sont toujours appliqués par le chef-client dans l'ordre suivant:
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.
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.