Puzzled about convergence, please advise?

I thought I understood this, so I’m puzzled that it’s not working the way I think it should work. I have the following simple recipe.

rpm_package “Installing RPM” do
action :install
package_name myRPM.rpm
end

template “/opt/some_path/conf/myRPMconfig.xml” do
source "myRPMconfig.xml.erb"
end

I expect both resources to be executed during convergence (run time), correct?

If so, the rpm_package should install myRPM.rpm, which creates the /opt/some_path/conf directory, so when the template resource runs, the directory is already there. However, when I run chef-client, I get an error saying “No such file or directory - /opt/some_path/conf”

I know that myRPM.rpm creates the directory because if I install it manually, it does create it.

Any advise?

Chris

resources are executed at converge time, but they are built (resource
collection) during compilation time. to build the template resource u need
to read the template file, inject variables and finally in converge tim
check if that differs from the existing one and replace it. so the resource
building part itself requires the file to be present.
you dont need template here, you want remote file with file:/// as source,
can you try that?
hope this help
ranjib

On Thu, Nov 13, 2014 at 12:21 PM, Fouts, Chris Chris.Fouts@sensus.com
wrote:

I thought I understood this, so I’m puzzled that it’s not working the
way I think it should work. I have the following simple recipe.

rpm_package “Installing RPM” do

action :install

package_name myRPM.rpm

end

template “/opt/some_path/conf/myRPMconfig.xml” do

source “myRPMconfig.xml.erb”

end

I expect both resources to be executed during convergence (run time),
correct?

If so, the rpm_package should install myRPM.rpm, which creates the
/opt/some_path/conf directory, so when the template resource runs, the
directory is already there. However, when I run chef-client, I get an error
saying “No such file or directory - /opt/some_path/conf”

I know that myRPM.rpm creates the directory because if I install it
manually, it does create it.

Any advise?

Chris

Sorry, I should’ve shown this example to explain why I “need” a template.

rpm_package “Installing RPM” do
action :install
package_name myRPM.rpm
end

template “/opt/some_path/conf/myRPMconfig.xml” do
source “myRPMconfig.xml.erb”
variable({
“var1” => node.mycookbook.var1
})
end

From: Ranjib Dey [mailto:dey.ranjib@gmail.com]
Sent: Thursday, November 13, 2014 3:46 PM
To: chef@lists.opscode.com
Subject: [chef] Re: Puzzled about convergence, please advise?

resources are executed at converge time, but they are built (resource collection) during compilation time. to build the template resource u need to read the template file, inject variables and finally in converge tim check if that differs from the existing one and replace it. so the resource building part itself requires the file to be present.
you dont need template here, you want remote file with file:///<file:///\> as source, can you try that?
hope this help
ranjib

On Thu, Nov 13, 2014 at 12:21 PM, Fouts, Chris <Chris.Fouts@sensus.commailto:Chris.Fouts@sensus.com> wrote:
I thought I understood this, so I’m puzzled that it’s not working the way I think it should work. I have the following simple recipe.

rpm_package “Installing RPM” do
action :install
package_name myRPM.rpm
end

template “/opt/some_path/conf/myRPMconfig.xml” do
source “myRPMconfig.xml.erb”
end

I expect both resources to be executed during convergence (run time), correct?

If so, the rpm_package should install myRPM.rpm, which creates the /opt/some_path/conf directory, so when the template resource runs, the directory is already there. However, when I run chef-client, I get an error saying “No such file or directory - /opt/some_path/conf”

I know that myRPM.rpm creates the directory because if I install it manually, it does create it.

Any advise?

Chris

The template resource does most of that work inside the provider at
compile-time. The resource is used to validate that your arguments to
the resource are valid, its not until you get into
define_resource_requirements inside of the provider that you would throw
the EnclosingDirectoryDoesNotExist exception.

As far as I can tell the example Chris gives should work, so we probably
need the real code and the real output showing the actual exception,
plus the backtrace. Offhand I'd suspect something more like a simple
"/opt/some_path/conf" vs. "/opt/some-path/conf" typo but there's not
enough information to say. However, I would have expected either an
EnclosingDirectoryDoesNotExist or the error message about the source of
the template not being found for the simple "file not found" cases that
I can think of. If chef is spitting back a stock "No such file or
directory" then I'm not sure what code path is getting hit without the
text of the exception and ideally the backtrace.

On 11/13/14, 12:46 PM, Ranjib Dey wrote:

resources are executed at converge time, but they are built (resource
collection) during compilation time. to build the template resource u
need to read the template file, inject variables and finally in
converge tim check if that differs from the existing one and replace
it. so the resource building part itself requires the file to be present.
you dont need template here, you want remote file with file:/// as
source, can you try that?
hope this help
ranjib

On Thu, Nov 13, 2014 at 12:21 PM, Fouts, Chris <Chris.Fouts@sensus.com
mailto:Chris.Fouts@sensus.com> wrote:

I thought I understood this, so I’m puzzled that it’s not working
the way I think it should work. I have the following simple recipe.

rpm_package “Installing RPM” do

  action :install

  package_name myRPM.rpm

end

template “/opt/some_path/conf/myRPMconfig.xml” do

  source “myRPMconfig.xml.erb”

end

I expect both resources to be executed during convergence (run
time), correct?

If so, the rpm_package should install myRPM.rpm, which creates the
/opt/some_path/conf directory, so when the template resource runs,
the directory is already there. However, when I run chef-client, I
get an error saying “No such file or directory  - /opt/some_path/conf”

I know that myRPM.rpm creates the directory because if I install
it manually, it does create it.

Any advise?

Chris

Try setting up your template with an action of nothing and then have the rpm_package resource notify the template.

rpm_package “Installing RPM” do
action :install
package_name myRPM.rpm

notifies :create, “template[/opt/some_path/conf/myRPMconfig.xml]”, :immediate
end

template “/opt/some_path/conf/myRPMconfig.xml” do
source "myRPMconfig.xml.erb"
variable({
“var1” => node.mycookbook.var1
})

action :nothing
end

From: Fouts, Chris [mailto:Chris.Fouts@Sensus.com]
Sent: Thursday, November 13, 2014 1:16 PM
To: chef@lists.opscode.com
Subject: [chef] RE: Re: Puzzled about convergence, please advise?

Sorry, I should’ve shown this example to explain why I “need” a template.

rpm_package “Installing RPM” do
action :install
package_name myRPM.rpm
end

template “/opt/some_path/conf/myRPMconfig.xml” do
source “myRPMconfig.xml.erb”
variable({
“var1” => node.mycookbook.var1
})
end

From: Ranjib Dey [mailto:dey.ranjib@gmail.com]
Sent: Thursday, November 13, 2014 3:46 PM
To: chef@lists.opscode.commailto:chef@lists.opscode.com
Subject: [chef] Re: Puzzled about convergence, please advise?

resources are executed at converge time, but they are built (resource collection) during compilation time. to build the template resource u need to read the template file, inject variables and finally in converge tim check if that differs from the existing one and replace it. so the resource building part itself requires the file to be present.
you dont need template here, you want remote file with file:///<file:///\> as source, can you try that?
hope this help
ranjib

On Thu, Nov 13, 2014 at 12:21 PM, Fouts, Chris <Chris.Fouts@sensus.commailto:Chris.Fouts@sensus.com> wrote:
I thought I understood this, so I’m puzzled that it’s not working the way I think it should work. I have the following simple recipe.

rpm_package “Installing RPM” do
action :install
package_name myRPM.rpm
end

template “/opt/some_path/conf/myRPMconfig.xml” do
source “myRPMconfig.xml.erb”
end

I expect both resources to be executed during convergence (run time), correct?

If so, the rpm_package should install myRPM.rpm, which creates the /opt/some_path/conf directory, so when the template resource runs, the directory is already there. However, when I run chef-client, I get an error saying “No such file or directory - /opt/some_path/conf”

I know that myRPM.rpm creates the directory because if I install it manually, it does create it.

Any advise?

Chris

Ok, here’s an actual trace. In this case, I have a recipe that installs Cassandra.

Service_name=”flexnet-cassandra”

rpm_package “Install Cassandra” do
action :install
package_name flexnet-cassandra.rpm
end

#Set Cassandra Clustered Config File
template “/opt/cassandra/conf/cassandra.yaml” do
source "cassandra.erb"
owner "root"
group "root"
mode 0755
variables(
:cassandra_hosts => node[:cassandra_hosts],
:environment => environment,
)
action :create
notifies :restart, “service[#{service_name}]”, :delayed
end

Recipe: cassandra::default

  • template[/opt/cassandra/conf/cassandra.yaml] action create
    • Parent directory /opt/cassandra/conf does not exist.
      ================================================================================
      Error executing action create on resource ‘template[/opt/cassandra/conf/cassandra.yaml]’
      ================================================================================

Chef::Exceptions::EnclosingDirectoryDoesNotExist

Parent directory /opt/cassandra/conf does not exist.

Resource Declaration:

In /var/chef/cache/cookbooks/cassandra/recipes/default.rb

18: template “/opt/cassandra/conf/cassandra.yaml” do
19: source "cassandra.erb"
20: owner "root"
21: group "root"
22: mode 0755
23: variables(
24: :cassandra_hosts => node[:cassandra_hosts],
25: :environment => environment,
26: )
27: action :create
28: notifies :restart, “service[#{service_name}]”, :delayed
29: end
30:

Compiled Resource:

Declared in /var/chef/cache/cookbooks/cassandra/recipes/default.rb:18:in `from_file’

template("/opt/cassandra/conf/cassandra.yaml") do
provider Chef::Provider::Template
action [:create]
retries 0
retry_delay 2
guard_interpreter :default
path "/opt/cassandra/conf/cassandra.yaml"
backup 5
atomic_update true
source "cassandra.erb"
variables {:cassandra_hosts=>[“scaleha-flip1”, “scaleha-flip2”, “scaleha-flex1”, “scaleha-flex2”], :environment=>“Flexapp Cluster”}
cookbook_name "cassandra"
recipe_name "default"
owner "root"
group "root"
mode 493
end

Running handlers:
[2014-11-13T16:42:07-05:00] ERROR: Running exception handlers
Running handlers complete

[2014-11-13T16:42:07-05:00] ERROR: Exception handlers complete
[2014-11-13T16:42:07-05:00] FATAL: Stacktrace dumped to /var/chef/cache/chef-stacktrace.out
Chef Client failed. 14 resources updated in 31.654667 seconds
[2014-11-13T16:42:07-05:00] ERROR: template[/opt/cassandra/conf/cassandra.yaml] (cassandra::default line 18) had an error: Chef::Exceptions::EnclosingDirectoryDoesNotExist: Parent directory /opt/cassandra/conf does not exist.
[2014-11-13T16:42:07-05:00] FATAL: Chef::Exceptions::ChildConvergeError: Chef run process exited unsuccessfully (exit code 1)
[root@scaleha-flip2 rpms]#

From: Lamont Granquist [mailto:lamont@opscode.com]
Sent: Thursday, November 13, 2014 4:41 PM
To: chef@lists.opscode.com
Subject: [chef] Re: Re: Puzzled about convergence, please advise?

The template resource does most of that work inside the provider at compile-time. The resource is used to validate that your arguments to the resource are valid, its not until you get into define_resource_requirements inside of the provider that you would throw the EnclosingDirectoryDoesNotExist exception.

As far as I can tell the example Chris gives should work, so we probably need the real code and the real output showing the actual exception, plus the backtrace. Offhand I’d suspect something more like a simple “/opt/some_path/conf” vs. “/opt/some-path/conf” typo but there’s not enough information to say. However, I would have expected either an EnclosingDirectoryDoesNotExist or the error message about the source of the template not being found for the simple “file not found” cases that I can think of. If chef is spitting back a stock “No such file or directory” then I’m not sure what code path is getting hit without the text of the exception and ideally the backtrace.

On 11/13/14, 12:46 PM, Ranjib Dey wrote:
resources are executed at converge time, but they are built (resource collection) during compilation time. to build the template resource u need to read the template file, inject variables and finally in converge tim check if that differs from the existing one and replace it. so the resource building part itself requires the file to be present.
you dont need template here, you want remote file with file:///<file:///\> as source, can you try that?
hope this help
ranjib

On Thu, Nov 13, 2014 at 12:21 PM, Fouts, Chris <Chris.Fouts@sensus.commailto:Chris.Fouts@sensus.com> wrote:
I thought I understood this, so I’m puzzled that it’s not working the way I think it should work. I have the following simple recipe.

rpm_package “Installing RPM” do
action :install
package_name myRPM.rpm
end

template “/opt/some_path/conf/myRPMconfig.xml” do
source “myRPMconfig.xml.erb”
end

I expect both resources to be executed during convergence (run time), correct?

If so, the rpm_package should install myRPM.rpm, which creates the /opt/some_path/conf directory, so when the template resource runs, the directory is already there. However, when I run chef-client, I get an error saying “No such file or directory - /opt/some_path/conf”

I know that myRPM.rpm creates the directory because if I install it manually, it does create it.

Any advise?

Chris

On Thursday, November 13, 2014 at 1:58 PM, Fouts, Chris wrote:

Ok, here’s an actual trace. In this case, I have a recipe that installs Cassandra.

Service_name=”flexnet-cassandra”

rpm_package “Install Cassandra” do
action :install
package_name flexnet-cassandra.rpm
end

#Set Cassandra Clustered Config File
template "/opt/cassandra/conf/cassandra.yaml" do
source "cassandra.erb"
owner "root"
group "root"
mode 0755
variables(
:cassandra_hosts => node[:cassandra_hosts],
:environment => environment,
)
action :create
notifies :restart, "service[#{service_name}]", :delayed
end

Recipe: cassandra::default

  • template[/opt/cassandra/conf/cassandra.yaml] action create
  • Parent directory /opt/cassandra/conf does not exist.
    ================================================================================
    Error executing action create on resource 'template[/opt/cassandra/conf/cassandra.yaml]'
    ================================================================================

Chef::Exceptions::EnclosingDirectoryDoesNotExist

Parent directory /opt/cassandra/conf does not exist.

Resource Declaration:

In /var/chef/cache/cookbooks/cassandra/recipes/default.rb

18: template "/opt/cassandra/conf/cassandra.yaml" do
19: source "cassandra.erb"
20: owner "root"
21: group "root"
22: mode 0755
23: variables(
24: :cassandra_hosts => node[:cassandra_hosts],
25: :environment => environment,
26: )
27: action :create
28: notifies :restart, "service[#{service_name}]", :delayed
29: end
30:

Compiled Resource:

Declared in /var/chef/cache/cookbooks/cassandra/recipes/default.rb:18:in `from_file'

template("/opt/cassandra/conf/cassandra.yaml") do
provider Chef::Provider::Template
action [:create]
retries 0
retry_delay 2
guard_interpreter :default
path "/opt/cassandra/conf/cassandra.yaml"
backup 5
atomic_update true
source "cassandra.erb"
variables {:cassandra_hosts=>["scaleha-flip1", "scaleha-flip2", "scaleha-flex1", "scaleha-flex2"], :environment=>"Flexapp Cluster"}
cookbook_name "cassandra"
recipe_name "default"
owner "root"
group "root"
mode 493
end

Running handlers:
[2014-11-13T16:42:07-05:00] ERROR: Running exception handlers
Running handlers complete

[2014-11-13T16:42:07-05:00] ERROR: Exception handlers complete
[2014-11-13T16:42:07-05:00] FATAL: Stacktrace dumped to /var/chef/cache/chef-stacktrace.out
Chef Client failed. 14 resources updated in 31.654667 seconds
[2014-11-13T16:42:07-05:00] ERROR: template[/opt/cassandra/conf/cassandra.yaml] (cassandra::default line 18) had an error: Chef::Exceptions::EnclosingDirectoryDoesNotExist: Parent directory /opt/cassandra/conf does not exist.
[2014-11-13T16:42:07-05:00] FATAL: Chef::Exceptions::ChildConvergeError: Chef run process exited unsuccessfully (exit code 1)

Another possibility is that the package doesn’t get installed for some reason. Could it already be installed but the conf/ dir has been removed? More generally, what’s on disk after Chef fails? It should have run the package resource before the template, so you should be able to observe the effects of running action :install on the package.

--
Daniel DeLeo

so on the server validate the rpm is installed:

rpm -qa | egrep flexnet-cassandra

validate the directory is in that rpm in the db:

rpm -ql flexnet-cassandra | egrep /opt/cassandra/conf

validate the directory exists:

ls -la /opt/cassandra/conf

based on the code you posted the rpm resource will have been converged
by the time you hit that check in the provider.

On Thu Nov 13 13:58:20 2014, Fouts, Chris wrote:

Ok, here’s an actual trace. In this case, I have a recipe that
installs Cassandra.

Service_name=”flexnet-cassandra”

rpm_package “Install Cassandra” do

action :install

package_name flexnet-cassandra.rpm

end

#Set Cassandra Clustered Config File

template "/opt/cassandra/conf/cassandra.yaml"do

source "cassandra.erb"

owner "root"

group "root"

mode 0755

variables(

:cassandra_hosts=> node[:cassandra_hosts],

:environment=> environment,

)

action :create

notifies :restart, "service[#{service_name}]", :delayed

end

Recipe: cassandra::default

  • template[/opt/cassandra/conf/cassandra.yaml] action create

  • Parent directory /opt/cassandra/conf does not exist.

================================================================================

Error executing action create on resource
'template[/opt/cassandra/conf/cassandra.yaml]'

================================================================================

Chef::Exceptions::EnclosingDirectoryDoesNotExist


Parent directory /opt/cassandra/conf does not exist.

Resource Declaration:


In /var/chef/cache/cookbooks/cassandra/recipes/default.rb

18: template "/opt/cassandra/conf/cassandra.yaml" do

19: source "cassandra.erb"

20: owner "root"

21: group "root"

22: mode 0755

23: variables(

24: :cassandra_hosts => node[:cassandra_hosts],

25: :environment => environment,

26: )

27: action :create

28: notifies :restart, "service[#{service_name}]", :delayed

29: end

30:

Compiled Resource:


Declared in

/var/chef/cache/cookbooks/cassandra/recipes/default.rb:18:in `from_file'

template("/opt/cassandra/conf/cassandra.yaml") do

provider Chef::Provider::Template

action [:create]

retries 0

retry_delay 2

guard_interpreter :default

path "/opt/cassandra/conf/cassandra.yaml"

backup 5

atomic_update true

source "cassandra.erb"

variables {:cassandra_hosts=>["scaleha-flip1", "scaleha-flip2",
"scaleha-flex1", "scaleha-flex2"], :environment=>"Flexapp Cluster"}

cookbook_name "cassandra"

recipe_name "default"

owner "root"

group "root"

mode 493

end

Running handlers:

[2014-11-13T16:42:07-05:00] ERROR: Running exception handlers

Running handlers complete

[2014-11-13T16:42:07-05:00] ERROR: Exception handlers complete

[2014-11-13T16:42:07-05:00] FATAL: Stacktrace dumped to
/var/chef/cache/chef-stacktrace.out

Chef Client failed. 14 resources updated in 31.654667 seconds

[2014-11-13T16:42:07-05:00] ERROR:
template[/opt/cassandra/conf/cassandra.yaml] (cassandra::default line
18) had an error: Chef::Exceptions::EnclosingDirectoryDoesNotExist:
Parent directory /opt/cassandra/conf does not exist.

[2014-11-13T16:42:07-05:00] FATAL:
Chef::Exceptions::ChildConvergeError: Chef run process exited
unsuccessfully (exit code 1)

[root@scaleha-flip2 rpms]#

*From:*Lamont Granquist [mailto:lamont@opscode.com]
Sent: Thursday, November 13, 2014 4:41 PM
To: chef@lists.opscode.com
Subject: [chef] Re: Re: Puzzled about convergence, please advise?

The template resource does most of that work inside the provider at
compile-time. The resource is used to validate that your arguments to
the resource are valid, its not until you get into
define_resource_requirements inside of the provider that you would
throw the EnclosingDirectoryDoesNotExist exception.

As far as I can tell the example Chris gives should work, so we
probably need the real code and the real output showing the actual
exception, plus the backtrace. Offhand I'd suspect something more
like a simple "/opt/some_path/conf" vs. "/opt/some-path/conf" typo but
there's not enough information to say. However, I would have expected
either an EnclosingDirectoryDoesNotExist or the error message about
the source of the template not being found for the simple "file not
found" cases that I can think of. If chef is spitting back a stock
"No such file or directory" then I'm not sure what code path is
getting hit without the text of the exception and ideally the backtrace.

On 11/13/14, 12:46 PM, Ranjib Dey wrote:

resources are executed at converge time, but they are built
(resource collection) during compilation time. to build the
template resource u need to read the template file, inject
variables and finally in converge tim check if that differs from
the existing one and replace it. so the resource building part
itself requires the file to be present.

you dont need template here, you want remote file with file:///
<file:///\> as source, can you try that?

hope this help

ranjib

On Thu, Nov 13, 2014 at 12:21 PM, Fouts, Chris
<Chris.Fouts@sensus.com mailto:Chris.Fouts@sensus.com> wrote:

I thought I understood this, so I’m puzzled that it’s not working
the way I think it should work. I have the following simple recipe.

rpm_package “Installing RPM” do

action :install

package_name myRPM.rpm

end

template “/opt/some_path/conf/myRPMconfig.xml” do

source “myRPMconfig.xml.erb”

end

I expect both resources to be executed during convergence (run
time), correct?

If so, the rpm_package should install myRPM.rpm, which creates the
/opt/some_path/conf directory, so when the template resource runs,
the directory is already there. However, when I run chef-client, I
get an error saying “No such file or directory - /opt/some_path/conf”

I know that myRPM.rpm creates the directory because if I install
it manually, it does create it.

Any advise?

Chris