# Cookbook sequentiality and variables

**URL:** <https://discourse.chef.io/t/cookbook-sequentiality-and-variables/2661>\
**Category:** Chef Infra (archive)\
**Created:** [April 11, 2012, 8:09pm UTC](https://discourse.chef.io/t/cookbook-sequentiality-and-variables/2661 "2012-04-11T20:09:42Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Motiejus\_Jakstys](https://sea2.discourse-cdn.com/flex016/user_avatar/discourse.chef.io/motiejus_jakstys/32/699_2.png) [@Motiejus\_Jakstys](https://discourse.chef.io/u/Motiejus_Jakstys)\
**Post date:** [April 11, 2012, 8:09pm UTC](https://discourse.chef.io/t/cookbook-sequentiality-and-variables/2661/1 "2012-04-11T20:09:42Z")

</div>

Hi,

I am modifying my first cookbook and have difficulties understanding how  
processing of commands work in Chef. Consider an extract from the cookbook:

search(:users, ‘groups:sysadmin’) do |u|

execute “delete password” do  
command "passwd -d #{u[‘id’]}"  
only\_if "test $(passwd -S #{u[‘id’]} | awk ‘{print $2}’) = L"  
end

end

There are two users in sysadmin data bag: motiejus and gavin. IMHO loop should  
be iterated twice. However, from chef-client logs I see this:

[Wed, 11 Apr 2012 20:58:24 +0100] INFO: Processing user[motiejus] action create (users::sysadmins line 42)  
[Wed, 11 Apr 2012 20:58:24 +0100] DEBUG: Processing execute[delete password] on [chef.src.gla.ac.uk](http://chef.src.gla.ac.uk)  
[Wed, 11 Apr 2012 20:58:24 +0100] INFO: Processing execute[delete password] action run (users::sysadmins line 52)  
[Wed, 11 Apr 2012 20:58:24 +0100] DEBUG: sh(test $(passwd -S motiejus | awk '{print 2}') = L) [Wed, 11 Apr 2012 20:58:24 +0100] DEBUG: Skipping execute[delete password] due to only\_if command `test (passwd -S motiejus | awk '{print 2}') = L` ... [Wed, 11 Apr 2012 20:59:26 +0100] DEBUG: Processing user[gavin] on chef.src.gla.ac.uk [Wed, 11 Apr 2012 20:59:26 +0100] INFO: Processing user[gavin] action create (users::sysadmins line 42) ... [Wed, 11 Apr 2012 20:59:26 +0100] DEBUG: Processing execute[delete password] on chef.src.gla.ac.uk [Wed, 11 Apr 2012 20:59:26 +0100] INFO: Processing execute[delete password] action run (users::sysadmins line 52) [Wed, 11 Apr 2012 20:59:26 +0100] DEBUG: sh(test (passwd -S motiejus | awk '{print 2}') = L) [Wed, 11 Apr 2012 20:59:26 +0100] DEBUG: Skipping execute[delete password] due to only\_if command `test (passwd -S motiejus | awk ‘{print $2}’) = L`

Notice the command

```
test $(passwd -S motiejus | awk '{print $2}') = L

```

is executed twice. I expect it to be executed once “motiejus”, second time  
"gavin". Any ideas why?

Another strange thing. If I replace  
only\_if "test $(passwd -S #{u[‘id’]} | awk ‘{print $2}’) = L"  
to  
only\_if "true " + u[‘id’]

I see this in the logs:

[Wed, 11 Apr 2012 21:03:40 +0100] INFO: Processing execute[delete password] action run (users::sysadmins line 52)  
[Wed, 11 Apr 2012 21:03:40 +0100] DEBUG: sh(true motiejus)  
[Wed, 11 Apr 2012 21:03:40 +0100] DEBUG: sh(true gavin)  
[Wed, 11 Apr 2012 21:03:41 +0100] INFO: execute[delete password] sh(passwd -d motiejus)  
passwd: password expiry information changed.  
[Wed, 11 Apr 2012 21:03:41 +0100] INFO: execute[delete password] ran successfully  
…  
[Wed, 11 Apr 2012 21:03:41 +0100] DEBUG: sh(true motiejus)  
[Wed, 11 Apr 2012 21:03:41 +0100] DEBUG: sh(true gavin)  
[Wed, 11 Apr 2012 21:03:41 +0100] INFO: execute[delete password] sh(passwd -d gavin)  
passwd: password expiry information changed.  
[Wed, 11 Apr 2012 21:03:41 +0100] INFO: execute[delete password] ran successfully

Why is sh(true ) executed twice? I expect it to run once for motiejus,  
and once for gavin.

Do I utterly misunderstand how cookbook execution works? I would like to know  
the details of compilation and execution, is there something more higher level  
than source code for me to look at (I don’t have much experience with ruby, so  
not that familiar with ruby metaprogramming)?

Chef 0.10.8 from opsocde apt repos on squeeze.

Thanks  
Motiejus

---

<div class="post-metadata">

**Author:** ![Jay\_Feldblum](https://avatars.discourse-cdn.com/v4/letter/j/9fc29f/32.png) [@Jay\_Feldblum](https://discourse.chef.io/u/Jay_Feldblum)\
**Post date:** [April 11, 2012, 10:16pm UTC](https://discourse.chef.io/t/cookbook-sequentiality-and-variables/2661/2 "2012-04-11T22:16:18Z")

</div>

Motiejus,

Resources that you create during the compilation phase to be executed by  
the system later during the convergence phase are _unique_ by their types  
and names.

You created a resource of type execute with name "delete password". The  
next time you call execute "delete password", it doesn't make a new  
resource. Instead, it finds the resource with that type and name, and  
reopens it so you can change resource attributes and add only-if/not-if  
blocks and add actions. In the end, there is only one resource of type  
execute with name "delete password".

Cheers,  
Jay Feldblum

On Wed, Apr 11, 2012 at 4:09 PM, Motiejus Jakštys [desired.mta@gmail.com](mailto:desired.mta@gmail.com)wrote:

> Hi,
> 
> I am modifying my first cookbook and have difficulties understanding how  
> processing of commands work in Chef. Consider an extract from the cookbook:
> 
> search(:users, 'groups:sysadmin') do |u|
> 
> execute "delete password" do  
> command "passwd -d #{u['id']}"  
> only\_if "test $(passwd -S #{u['id']} | awk '{print $2}') = L"  
> end
> 
> end
> 
> There are two users in sysadmin data bag: motiejus and gavin. IMHO loop  
> should  
> be iterated twice. However, from chef-client logs I see this:
> 
> [Wed, 11 Apr 2012 20:58:24 +0100] INFO: Processing user[motiejus] action  
> create (users::sysadmins line 42)  
> [Wed, 11 Apr 2012 20:58:24 +0100] DEBUG: Processing execute[delete  
> password] on [chef.src.gla.ac.uk](http://chef.src.gla.ac.uk)  
> [Wed, 11 Apr 2012 20:58:24 +0100] INFO: Processing execute[delete  
> password] action run (users::sysadmins line 52)  
> [Wed, 11 Apr 2012 20:58:24 +0100] DEBUG: sh(test $(passwd -S motiejus |  
> awk '{print $2}') = L)  
> [Wed, 11 Apr 2012 20:58:24 +0100] DEBUG: Skipping execute[delete password]  
> due to only\_if command `test $(passwd -S motiejus | awk '{print $2}') = L`  
> ...  
> [Wed, 11 Apr 2012 20:59:26 +0100] DEBUG: Processing user[gavin] on  
> [chef.src.gla.ac.uk](http://chef.src.gla.ac.uk)  
> [Wed, 11 Apr 2012 20:59:26 +0100] INFO: Processing user[gavin] action  
> create (users::sysadmins line 42)  
> ...  
> [Wed, 11 Apr 2012 20:59:26 +0100] DEBUG: Processing execute[delete  
> password] on [chef.src.gla.ac.uk](http://chef.src.gla.ac.uk)  
> [Wed, 11 Apr 2012 20:59:26 +0100] INFO: Processing execute[delete  
> password] action run (users::sysadmins line 52)  
> [Wed, 11 Apr 2012 20:59:26 +0100] DEBUG: sh(test $(passwd -S motiejus |  
> awk '{print $2}') = L)  
> [Wed, 11 Apr 2012 20:59:26 +0100] DEBUG: Skipping execute[delete password]  
> due to only\_if command `test $(passwd -S motiejus | awk '{print $2}') = L`
> 
> Notice the command
> 
> test $(passwd -S motiejus | awk '{print $2}') = L
> 
> is executed twice. I expect it to be executed once "motiejus", second time  
> "gavin". Any ideas why?
> 
> Another strange thing. If I replace  
> only\_if "test $(passwd -S #{u['id']} | awk '{print $2}') = L"  
> to  
> only\_if "true " + u['id']
> 
> I see this in the logs:
> 
> [Wed, 11 Apr 2012 21:03:40 +0100] INFO: Processing execute[delete  
> password] action run (users::sysadmins line 52)  
> [Wed, 11 Apr 2012 21:03:40 +0100] DEBUG: sh(true motiejus)  
> [Wed, 11 Apr 2012 21:03:40 +0100] DEBUG: sh(true gavin)  
> [Wed, 11 Apr 2012 21:03:41 +0100] INFO: execute[delete password] sh(passwd  
> -d motiejus)  
> passwd: password expiry information changed.  
> [Wed, 11 Apr 2012 21:03:41 +0100] INFO: execute[delete password] ran  
> successfully  
> ...  
> [Wed, 11 Apr 2012 21:03:41 +0100] DEBUG: sh(true motiejus)  
> [Wed, 11 Apr 2012 21:03:41 +0100] DEBUG: sh(true gavin)  
> [Wed, 11 Apr 2012 21:03:41 +0100] INFO: execute[delete password] sh(passwd  
> -d gavin)  
> passwd: password expiry information changed.  
> [Wed, 11 Apr 2012 21:03:41 +0100] INFO: execute[delete password] ran  
> successfully
> 
> Why is sh(true ) executed twice? I expect it to run once for  
> motiejus,  
> and once for gavin.
> 
> Do I utterly misunderstand how cookbook execution works? I would like to  
> know  
> the details of compilation and execution, is there something more higher  
> level  
> than source code for me to look at (I don't have much experience with  
> ruby, so  
> not that familiar with ruby metaprogramming)?
> 
> Chef 0.10.8 from opsocde apt repos on squeeze.
> 
> Thanks  
> Motiejus

---

<div class="post-metadata">

**Author:** ![Motiejus\_Jakstys](https://sea2.discourse-cdn.com/flex016/user_avatar/discourse.chef.io/motiejus_jakstys/32/699_2.png) [@Motiejus\_Jakstys](https://discourse.chef.io/u/Motiejus_Jakstys)\
**Post date:** [April 12, 2012, 6:10am UTC](https://discourse.chef.io/t/cookbook-sequentiality-and-variables/2661/3 "2012-04-12T06:10:15Z")

</div>

On Wed, Apr 11, 2012 at 06:16:18PM -0400, Jay Feldblum wrote:

> Motiejus,
> 
> Resources that you create during the compilation phase to be executed by  
> the system later during the convergence phase are _unique_ by their types  
> and names.
> 
> You created a resource of type execute with name "delete password". The  
> next time you call execute "delete password", it doesn't make a new  
> resource. Instead, it finds the resource with that type and name, and  
> reopens it so you can change resource attributes and add only-if/not-if  
> blocks and add actions. In the end, there is only one resource of type  
> execute with name "delete password".

I looked for a way to execute a query without creating a resource, but didn't  
find one. I looked at apt and chef-client cookbooks for an example and tried to  
google for it. All "executions" are handled when creating an "execute" named block.

OK, clearer, thanks. So once string is evaluated in the resource, it will stay  
like this.

This is what I came up with:

execute "delete password for " + u['id'] do  
command "passwd -d #{u['id']}"  
only\_if "test $(passwd -S #{u['id']} | awk '{print $2}') = L"  
end

I don't like it. Is there a better way to do it, or is it the way to do it?

Jay, thanks for your explanations. 🙂 A tutorial or higher-level documentation  
would be useful here, so I wouldn't ask those kind of basic questions. We'll  
see what I can do about it when I learn chef.

Motiejus

---

<div class="post-metadata">

**Author:** ![Jay\_Feldblum](https://avatars.discourse-cdn.com/v4/letter/j/9fc29f/32.png) [@Jay\_Feldblum](https://discourse.chef.io/u/Jay_Feldblum)\
**Post date:** [April 12, 2012, 10:52am UTC](https://discourse.chef.io/t/cookbook-sequentiality-and-variables/2661/4 "2012-04-12T10:52:08Z")

</div>

Motiejus,

That looks fine to me.

Cheers,  
Jay

On Thu, Apr 12, 2012 at 2:10 AM, Motiejus Jakštys [desired.mta@gmail.com](mailto:desired.mta@gmail.com)wrote:

> On Wed, Apr 11, 2012 at 06:16:18PM -0400, Jay Feldblum wrote:
> 
> > Motiejus,
> > 
> > Resources that you create during the compilation phase to be executed by  
> > the system later during the convergence phase are _unique_ by their types  
> > and names.
> > 
> > You created a resource of type execute with name "delete password". The  
> > next time you call execute "delete password", it doesn't make a new  
> > resource. Instead, it finds the resource with that type and name, and  
> > reopens it so you can change resource attributes and add only-if/not-if  
> > blocks and add actions. In the end, there is only one resource of type  
> > execute with name "delete password".
> 
> I looked for a way to execute a query without creating a resource, but  
> didn't  
> find one. I looked at apt and chef-client cookbooks for an example and  
> tried to  
> google for it. All "executions" are handled when creating an "execute"  
> named block.
> 
> OK, clearer, thanks. So once string is evaluated in the resource, it will  
> stay  
> like this.
> 
> This is what I came up with:
> 
> execute "delete password for " + u['id'] do  
> command "passwd -d #{u['id']}"  
> only\_if "test $(passwd -S #{u['id']} | awk '{print $2}') = L"  
> end
> 
> I don't like it. Is there a better way to do it, or is it the way to do it?
> 
> Jay, thanks for your explanations. 🙂 A tutorial or higher-level  
> documentation  
> would be useful here, so I wouldn't ask those kind of basic questions.  
> We'll  
> see what I can do about it when I learn chef.
> 
> Motiejus
