3 votes

Chef, ruby hashes et templates

Je sais que c'est plus une ruby question que chef mais...

J'ai quelques attributs comme :

default['my_cookbook']['some_namespace1']['some_attribute1'] = 'some_value1'
default['my_cookbook']['some_namespace1']['some_attribute2'] = 'some_value2'
default['my_cookbook']['some_namespace1']['some_attribute2'] = 'some_value3'
...
default['my_cookbook']['some_namespace2']['some_attribute1'] = 'some_value1'
default['my_cookbook']['some_namespace2']['some_attribute2'] = 'some_value2'
default['my_cookbook']['some_namespace2']['some_attribute2'] = 'some_value3'
...

D'autre part, je crée une ressource modèle comme ceci :

template 'template_name' do
  source 'template_source.erb'
  variables (
    my_namespace_1: node['my_cookbook']['some_namespace1'],
    my_namespace_2: node['my_cookbook']['some_namespace2']
  )
end

Ensuite, dans le template_source.erb J'essaie :

...
<%= @my_namespace_1['some_attribute1'] %> #=> 'some_value1'
...

Cependant, lorsque je lance Kitchen, j'obtiens ceci, au lieu de 'some_value1' :

Chef::Mixin::Template::TemplateError
------------------------------------
undefined method `[]' for nil:NilClass

Comment dois-je envoyer la variable du modèle pour l'utiliser de cette façon ?

4voto

papirtiger Points 1870

EDIT : Ceci ne s'applique qu'à Ruby en général et non à Chef en particulier.

Passe un hachage imbriqué :

template 'template_name' do
  source 'template_source.erb'
  variables (
    my_namespace_1: {
      some_attribute1: node['my_cookbook']['some_namespace1']['some_attribute1']
    }
  )
end

Mais plutôt que de copier les valeurs mot à mot, vous pouvez utiliser toute la puissance de la fonction Classe de hachage pour trancher, couper en dés et fusionner tout ce que vous voulez :

template 'template_name' do
  source 'template_source.erb'
  variables (
    node['my_cookbook'].slice('some_namespace1', 'some_namespace2')
  )
end

L'un des problèmes que vous avez rencontrés en Ruby est que les symboles sont généralement utilisés comme clés de hachage :

# newer literal syntax
a_hash = {
  foo: 'bar'
}

# or with the older hash-rocket syntax
a_hash = {
  :foo => 'bar'
}

Les symboles sont extrêmement efficaces puisqu'il s'agit de chaînes internées stockées dans une table. Lorsque vous comparez des symboles, vous comparez l'ID de l'objet au lieu de comparer chaque caractère de la chaîne.

En fait, les chaînes ne sont vraiment utilisées que lorsque vous voulez des clés dans le hachage qui ne sont pas des symboles Ruby valides - comme lors de la construction d'un hachage d'en-têtes HTTP.

Ruby ne traite pas indifféremment les clés de symboles et de chaînes de caractères :

{
  foo: 'bar'
}[:foo] 
# => bar

{
  foo: 'bar'
}['foo'] 
# => nil

Ainsi, pour accéder à la variable passée dans le modèle, vous devez utiliser :

<%= @my_namespace_1[:some_attribute1] %>

0voto

coderanger Points 389

Ce que vous avez dans l'exemple devrait fonctionner. Je suppose que vous avez une faute de frappe quelque part dans votre recette originale que vous avez corrigée lors de la générification du code.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X