Robin
Robin

Reputation: 4260

Can't embed bash command in to Chef Recipe

I'm attempting to embed a shell command in to my Chef Recipe, however when Chef executes the command it seems to get things wrong. Here's the resource in question:

script "create libs symlink" do
  interpreter "bash"
  user "root"
  cwd "/home/robin/test"
  code <<-EOH
ln -s $(ls -1 | grep '^[0-9.-]\+$') curr-version-libs
  EOH
end

The /home/robin/test directory contains a folder called 19.26-3, so I'm expecting a symlink called curr-version-libs pointing at 19.26-3.

Instead, I'm ending up with a circular symlink:

drwxr-xr-x 4 root root  4096 Jan 17 22:35 19.26-3
drwxr-xr-x 2 root root  4096 Jan 17 22:35 config
lrwxrwxrwx 1 root root    17 Jan 28 17:31 curr-version-libs -> curr-version-libs

It seems that the $(ls -1 | grep '^[0-9.-]+$') is being removed and I'm ending up with the command ln -s curr-version-libs.

Does anyone know what's going on here? I've tried using an execute resource, but I get the same results.

Upvotes: 3

Views: 2537

Answers (3)

Jordan Dea-Mattson
Jordan Dea-Mattson

Reputation: 5821

It appears you are calling out to the shell to create a sym link. In that case, a much better way to do this is to use the Chef link resource. I would never use the script or execute resource to do what you are doing.

Using the link resource, you would do the following:

  link "/home/robin/test/curr-version-libs" do
    to '/home/robin/test/19.26-3'
    user 'root'
    group 'root'
    link_type :symbolic 
    action :create
  end

A quick side commentary: I have mentored and tutored a number of folks to come up on Chef. Those who come to understand what is offered by the resources, providers, and lightweight resources (aka. LWRPs) are much happier and effective than those who just try to drop their old shell scripts into their cookbooks.

I highly recommend reading the Resource and Providers and Lightweight Resources Documentation

Upvotes: 1

Draco Ater
Draco Ater

Reputation: 21226

If your 19.26-3 directory exists before chef run starts, then it is easy. If you are creating a symbolic link, I would recommend using link resource for that.

version = `ls /home/robin/test/ -1 | grep '^[0-9.-]+$'`.strip

link "/home/robin/test/curr-version-libs" do
  to ::File.join( "/home/robin/test", version )
end

But if it is not there, I would recommend using ruby_block and defining your link resource dynamically.

ruby_block "create libs symlink" do
  block do
    version = `ls /home/robin/test/ -1 | grep '^[0-9.-]+$'`.strip
    res = Chef::Resource::Link.new( "/home/robin/test/curr-version-libs", run_context )
    res.to ::File.join( "/home/robin/test", version )
    res.run_action :create
  end
end

Edit: I corrected the answer by fixing regex and and calling strip before assigning to version as Robin proposed.

Upvotes: 4

Llu&#237;s
Llu&#237;s

Reputation: 1317

have you tried escaping dollar sign?

ln -s \$(ls -1 | grep '^[0-9.-]\+$') curr-version-libs

Upvotes: 0

Related Questions