[chef] Re: Re: Re: Re: Re: Re: How to override node attribute with lazy value?


Chronological Thread 
  • From: Lamont Granquist < >
  • To: Greg Barker < >
  • Cc: " " < >
  • Subject: [chef] Re: Re: Re: Re: Re: Re: How to override node attribute with lazy value?
  • Date: Thu, 09 Oct 2014 20:39:06 -0700


"setting the automatic_attrs" wasn't really the point of that code I pasted there.  the point is to execute it at compile time rather than converge time.  the code you point to in the system cookbook is inside of a provider and will also get executed at converge time.  you can call the system_hostname LWRP yourself and force it to run at compile time by method chaining .run_action(:set) off of it (and add an `action :nothing` attribute inside the LWRP).

On 10/9/14, 8:13 PM, Greg Barker wrote:
" type="cite">
Thanks Lamont. I tried using the system cookbook which seems to do as you have suggested (setting the automatic_attrs) but it still doesn't work.

The system cookbook is first in my run list and then towards the end it gets to my recipe which contains:
node.override["chef-server"]["configuration"]["nginx"]["ssl_certificate"] = "/etc/pki/tls/certs/#{node['fqdn']}.pem"
...but it still thinks node['fqdn'] is localhost, it doesn't get the updated value.

I guess I will just have to steer clear of relying on node['fqdn'] unless you have any other ideas, it's a bummer that so many cookbooks use it though.

Greg

On Sat, Oct 4, 2014 at 10:27 AM, Lamont Granquist < " target="_blank"> > wrote:
On 10/3/14, 5:13 PM, Lamont Granquist wrote:
On Fri Oct  3 16:39:36 2014, Lamont Granquist wrote:

How it should be written, i'll look at submitting a PR...


Sorry look like I fell victim to thinking that all problems were like my last problem.

The hostname is getting set at converge time, fairly late, by the hostname cookbook.  Your node['fqdn'] will be the old hostname throughout the whole compile phase of the chef-client run.  In your case since you control the code it'll be way easier to use the node['set_fqdn'] attribute that you're passing to the hostname cookbook to pass to the
chef-server cookbook:

node.override["chef-server"]["configuration"]["nginx"]["ssl_certificate"] = "/etc/pki/tls/certs/#{node['set_fqdn']}.pem"

If that doesn't work for you then you may have an issue trying to do that.  The attributes are most likely getting passed into the template variable sometime in compiletime and your node['fqdn'] isn't getting updated until converge time.   Either the hostname cookbook needs to be changed to do its work at compile-time or else the chef-server cookbook needs to be converted to be lazy.

A better approach would probably be for the hostname cookbook to expose a ruby library to call to get the desired hostname (basically sugar around either returning node['set_fqdn'] or else returning the output of "/usr/sbin/vmtoolsd --cmd 'info-get guestinfo.hostname'") and then you could get that value at compile time and set attributes with it just fine.


So, I'd actually suggest doing something more like this than using that hostname cookbook:

self.class.send(:include, Chef::Mixin::ShellOut)

# execute very early
execute "set hostname to nodename" do
  command "/bin/hostname #{node.name}"
  action :nothing
  not_if "shell_out!('hostname').stdout.chomp == node.name"
end.run_action(:run)

# fake out ohai data
node.automatic_attrs["hostname"] = node.name[/[^\.]*/]
node.automatic_attrs["domain"] = node.name[/\.(.*)/, 1]
node.automatic_attrs["machinename"] = node.name
node.automatic_attrs["fqdn"] = node.name

case node["platform_family"]
when "rhel", "fedora"
  template "/etc/sysconfig/network" do
    source "redhat-network.erb"
  end
when "debian"
  template "/etc/hostname" do
    source "ubuntu-hostname.erb"
  end
end

That encodes my policy that node names are fqdns and that the fqdn is set from the node name and that hostnames are fqdns.  If you have a different policy, you can modify that code.  The important bit is that I set the hostname of the box at compile time at the top of my run_list.  Then I override the ohai automatic attrs at compile time so that all later code will see that.  The templates can wait until converge time since those are only going to be necessary on next boot.

You can quibble with this because clearly there's a problem with separation of concerns and we "should" be calling ohai to reload the node data, but if you do that, you need to make sure that you're doing that at compile time.  You could wrap the hostname cookbook's recipe logic in an LWRP and then simply force that to run at compile time.  I don't care about that because I know what the ohai policy on those attrs are and that we're unlikely to change it so I'm not too concerned about duplicating the code and forcing it like that.

And the function of setting the current hostname and fixing the ohai data is separate from the function of updating the templates.  If I was doing this reusably I'd keep those separate.  I'd also keep 'finding the hostname' separate and probably just put that in a straight up ruby library function.  That would be function or set of functions that you could use to poke vmware or xenserver or whatever to see what your hostname is set as in the hypervisor and use that.






Archive powered by MHonArc 2.6.16.

§