Setting node attr if certain process is running

Hiya,

I’m creating an internal CI service for my group, and there’s this bit I’m
trying to implement, but it’s not working yet. I’m hoping someone could provide
tips. It is possible I’m going about this in an anti-pattern way. Feedback
appreciated:

When a “worker” node is launched (ec2), a master CI node waits for the worker
node to finish running chef and become ready to take commands from the master CI
node. My idea is, the master CI node polls the chef API looking for a certain
node attribute of this particular worker node.

On the worker node, in the first chef run, I want to have it set for itself an
attribute that indicates it’s “ready”. If it’s not ready, it’s “pending”. For
now, let’s just say node’s readiness is satisfied if mysql is running. If it’s
running, the node should set this attr within the recipe:

node.set[‘macabre’][‘salad’][‘bacon’][‘state’] = “ready”

But I’m failing at getting the node to set this correctly.

This code below was my first try, but it doesn’t work at all in that it falsely
sets “ready” every chef run, regardless if mysql is running or not. Should this
work the way I’ve written it?

This is falsely setting “ready” every time

if /sbin/pidof mysql >/dev/null 2>&1
Chef::Log.debug(“HIGGS-BOSON: setting bacon state ready”)
node.set[‘macabre’][‘salad’][‘bacon’][‘state’] = "ready"
else
Chef::Log.debug(“HIGGS-BOSON: setting bacon state pending”)
node.set[‘macabre’][‘salad’][‘bacon’][‘state’] = "pending"
end

And here’s my second try. It’s failing in that it takes 2 chef client runs to
actually get the correct state reported: if current node attr state is “ready”,
I stop mysql, then run chef again, the state gets set to “ready” again. But upon
a second chef run, with mysql still stopped, the state correctly gets set to
"pending". When I see this kind of thing happening, it tells me I need to think
about the chef client run in compile time vs run time. I tried the following,
but it takes 2 chef client runs to see the correct state:

e = execute “is mysql running” do
action :nothing
command “sleep 0"
user “root"
pidfile=”/var/lib/mysql/#{node[‘fqdn’]}.pid"
if File.exists?(”#{pidfile}")
Chef::Log.debug(“HIGGS-BOSON: setting bacon state ready. pidfile: #{pidfile}”)
node.set[‘macabre’][‘salad’][‘bacon’][‘state’] = "ready"
else
Chef::Log.debug(“HIGGS-BOSON: setting bacon state pending”)
node.set[‘macabre’][‘salad’][‘bacon’][‘state’] = "pending"
end

end

e.run_action(:run)

So, yeah. Any advice?

TIA,
kallen

On Tuesday, September 3, 2013 at 2:42 PM, kallen@groknaut.net wrote:

Hiya,

I'm creating an internal CI service for my group, and there's this bit I'm
trying to implement, but it's not working yet. I'm hoping someone could provide
tips. It is possible I'm going about this in an anti-pattern way. Feedback
appreciated:

When a "worker" node is launched (ec2), a master CI node waits for the worker
node to finish running chef and become ready to take commands from the master CI
node. My idea is, the master CI node polls the chef API looking for a certain
node attribute of this particular worker node.

On the worker node, in the first chef run, I want to have it set for itself an
attribute that indicates it's "ready". If it's not ready, it's "pending". For
now, let's just say node's readiness is satisfied if mysql is running. If it's
running, the node should set this attr within the recipe:

node.set['macabre']['salad']['bacon']['state'] = "ready"

But I'm failing at getting the node to set this correctly.

This code below was my first try, but it doesn't work at all in that it falsely
sets "ready" every chef run, regardless if mysql is running or not. Should this
work the way I've written it?

This is falsely setting "ready" every time

if /sbin/pidof mysql >/dev/null 2>&1

This returns a string which is a "truthy" value in ruby. You can use system("command") instead.

Chef::Log.debug("HIGGS-BOSON: setting bacon state ready")
node.set['macabre']['salad']['bacon']['state'] = "ready"
else
Chef::Log.debug("HIGGS-BOSON: setting bacon state pending")
node.set['macabre']['salad']['bacon']['state'] = "pending"
end

And here's my second try. It's failing in that it takes 2 chef client runs to
actually get the correct state reported: if current node attr state is "ready",
I stop mysql, then run chef again, the state gets set to "ready" again. But upon
a second chef run, with mysql still stopped, the state correctly gets set to
"pending". When I see this kind of thing happening, it tells me I need to think
about the chef client run in compile time vs run time. I tried the following,
but it takes 2 chef client runs to see the correct state:

e = execute "is mysql running" do
action :nothing
command "sleep 0"
user "root"
pidfile="/var/lib/mysql/#{node['fqdn']}.pid"
if File.exists?("#{pidfile}")
Chef::Log.debug("HIGGS-BOSON: setting bacon state ready. pidfile: #{pidfile}")
node.set['macabre']['salad']['bacon']['state'] = "ready"
else
Chef::Log.debug("HIGGS-BOSON: setting bacon state pending")
node.set['macabre']['salad']['bacon']['state'] = "pending"
end

end

e.run_action(:run)
You probably want a ruby_block resource here. The part of a resource declaration inside the do…end is evaluated immediately at compile time.

So, yeah. Any advice?

TIA,
kallen

HTH,

--
Daniel DeLeo

ruby_block! That's right, I knew execute didn't feel right.

I'll give your advice a try. Thanks Daniel.

kallen

On Tue, 03 Sep 2013, Daniel DeLeo wrote:

On Tuesday, September 3, 2013 at 2:42 PM, kallen@groknaut.net wrote:

Hiya,

I'm creating an internal CI service for my group, and there's this bit I'm
trying to implement, but it's not working yet. I'm hoping someone could provide
tips. It is possible I'm going about this in an anti-pattern way. Feedback
appreciated:

When a "worker" node is launched (ec2), a master CI node waits for the worker
node to finish running chef and become ready to take commands from the master CI
node. My idea is, the master CI node polls the chef API looking for a certain
node attribute of this particular worker node.

On the worker node, in the first chef run, I want to have it set for itself an
attribute that indicates it's "ready". If it's not ready, it's "pending". For
now, let's just say node's readiness is satisfied if mysql is running. If it's
running, the node should set this attr within the recipe:

node.set['macabre']['salad']['bacon']['state'] = "ready"

But I'm failing at getting the node to set this correctly.

This code below was my first try, but it doesn't work at all in that it falsely
sets "ready" every chef run, regardless if mysql is running or not. Should this
work the way I've written it?

This is falsely setting "ready" every time

if /sbin/pidof mysql >/dev/null 2>&1

This returns a string which is a "truthy" value in ruby. You can use system("command") instead.

Chef::Log.debug("HIGGS-BOSON: setting bacon state ready")
node.set['macabre']['salad']['bacon']['state'] = "ready"
else
Chef::Log.debug("HIGGS-BOSON: setting bacon state pending")
node.set['macabre']['salad']['bacon']['state'] = "pending"
end

And here's my second try. It's failing in that it takes 2 chef client runs to
actually get the correct state reported: if current node attr state is "ready",
I stop mysql, then run chef again, the state gets set to "ready" again. But upon
a second chef run, with mysql still stopped, the state correctly gets set to
"pending". When I see this kind of thing happening, it tells me I need to think
about the chef client run in compile time vs run time. I tried the following,
but it takes 2 chef client runs to see the correct state:

e = execute "is mysql running" do
action :nothing
command "sleep 0"
user "root"
pidfile="/var/lib/mysql/#{node['fqdn']}.pid"
if File.exists?("#{pidfile}")
Chef::Log.debug("HIGGS-BOSON: setting bacon state ready. pidfile: #{pidfile}")
node.set['macabre']['salad']['bacon']['state'] = "ready"
else
Chef::Log.debug("HIGGS-BOSON: setting bacon state pending")
node.set['macabre']['salad']['bacon']['state'] = "pending"
end

end

e.run_action(:run)
You probably want a ruby_block resource here. The part of a resource declaration inside the do???end is evaluated immediately at compile time.

So, yeah. Any advice?

TIA,
kallen

HTH,

--
Daniel DeLeo