# Easier symlink management?

**URL:** <https://discourse.chef.io/t/easier-symlink-management/2150>\
**Category:** Chef Infra (archive)\
**Created:** [October 28, 2011, 5:17pm UTC](https://discourse.chef.io/t/easier-symlink-management/2150 "2011-10-28T17:17:49Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Peter\_Norton](https://avatars.discourse-cdn.com/v4/letter/p/dec6dc/32.png) [@Peter\_Norton](https://discourse.chef.io/u/Peter_Norton)\
**Post date:** [October 28, 2011, 5:17pm UTC](https://discourse.chef.io/t/easier-symlink-management/2150/1 "2011-10-28T17:17:49Z")

</div>

I’m migrating installations over to chef that currently do a lot of  
symlinking. The actual symlinks make sense, but don’t adhere to the  
rails/capistrano layout deployed in the chef documentation for the  
deploy mechanism. It seems to me that the deploy mechanism is more  
than I want - I’d like to be able to do

symlink\_dir “foo” do  
user myuser  
group mygroup  
obj\_types [‘d’, ‘l’, ‘f’]  
source /source/filesystem/path  
dest /destination/filesystem/path  
end

and have all files, directories, and symlinks be symlinked from  
src-\>dst. Instead it seems that I have to do this:

bash “create\_bin\_symlinks” do  
# Binary symlinks don’t get directories linked in.  
user 'user’  
group 'group’  
cwd dst\_dir  
code \<\<-EOBASH  
for item in $(ls #{src\_dir}) ; do  
if [-x #{src\_dir}/$item] && [! -d #{src\_dir}/$item] ; then  
[-h #{dst\_dir}/$item] || ln -s #{src\_dir}/$item #{dst\_dir}/  
fi  
done  
EOBASH  
end

and tailor this a bit for each file type that I want, which means I’ll  
be littering a dozen cookbooks and 3x that recipes with this sort of  
thing.

How could I add to the DSL to create the feature I described here? In  
fact, how could I do it such that the obj\_types could be augmented by  
passing in a callback to a filter function so instead of just types I  
could use any property of the file to determine whether or not to make  
the symlink in the source and dest?

Thanks,

-Peter

---

<div class="post-metadata">

**Author:** ![Andrea\_Campi](https://sea2.discourse-cdn.com/flex016/user_avatar/discourse.chef.io/andrea_campi/32/514_2.png) [@Andrea\_Campi](https://discourse.chef.io/u/Andrea_Campi)\
**Post date:** [October 28, 2011, 6:34pm UTC](https://discourse.chef.io/t/easier-symlink-management/2150/2 "2011-10-28T18:34:25Z")

</div>

An LWRP can do what you want; looking at your example you would have a "symlink\_dir" resource, and "source", "dest" etc would be providers.  
In your action you need to define your logic (iterating over all your files and calling the standard link provider do perform the actual link).

Read up on LWRPs in the wiki, or just look at the existing providers in the chef gem.

For an example of passing a block and calling it, see [https://github.com/opscode/chef/blob/master/chef/lib/chef/resource/ruby\_block.rb](https://github.com/opscode/chef/blob/master/chef/lib/chef/resource/ruby_block.rb) and the matching [https://github.com/opscode/chef/blob/master/chef/lib/chef/provider/ruby\_block.rb](https://github.com/opscode/chef/blob/master/chef/lib/chef/provider/ruby_block.rb)

Andrea

On Oct 28, 2011, at 7:17 PM, Peter Norton [pn+chef-list@knewton.com](mailto:pn+chef-list@knewton.com) wrote:

> I'm migrating installations over to chef that currently do a lot of  
> symlinking. The actual symlinks make sense, but don't adhere to the  
> rails/capistrano layout deployed in the chef documentation for the  
> deploy mechanism. It seems to me that the deploy mechanism is more  
> than I want - I'd like to be able to do
> 
> symlink\_dir "foo" do  
> user myuser  
> group mygroup  
> obj\_types ['d', 'l', 'f']  
> source /source/filesystem/path  
> dest /destination/filesystem/path  
> end
> 
> and have all files, directories, and symlinks be symlinked from  
> src-\>dst. Instead it seems that I have to do this:
> 
> bash "create\_bin\_symlinks" do
> 
> # Binary symlinks don't get directories linked in.
> 
> user 'user'  
> group 'group'  
> cwd dst\_dir  
> code \<\<-EOBASH  
> for item in $(ls #{src\_dir}) ; do  
> if [-x #{src\_dir}/$item] && [! -d #{src\_dir}/$item] ; then  
> [-h #{dst\_dir}/$item] || ln -s #{src\_dir}/$item #{dst\_dir}/  
> fi  
> done  
> EOBASH  
> end
> 
> and tailor this a bit for each file type that I want, which means I'll  
> be littering a dozen cookbooks and 3x that recipes with this sort of  
> thing.
> 
> How could I add to the DSL to create the feature I described here? In  
> fact, how could I do it such that the obj\_types could be augmented by  
> passing in a callback to a filter function so instead of just types I  
> could use any property of the file to determine whether or not to make  
> the symlink in the source and dest?
> 
> Thanks,
> 
> -Peter

---

<div class="post-metadata">

**Author:** ![Peter\_Norton](https://avatars.discourse-cdn.com/v4/letter/p/dec6dc/32.png) [@Peter\_Norton](https://discourse.chef.io/u/Peter_Norton)\
**Post date:** [October 28, 2011, 8:01pm UTC](https://discourse.chef.io/t/easier-symlink-management/2150/3 "2011-10-28T20:01:51Z")

</div>

Thanks, I'll look at how LWRPs work. I didn't realize they were there  
to be customized in this manner.

-Peter

On Fri, Oct 28, 2011 at 2:34 PM, Andrea Campi  
[andrea.campi@zephirworks.com](mailto:andrea.campi@zephirworks.com) wrote:

> An LWRP can do what you want; looking at your example you would have a "symlink\_dir" resource, and "source", "dest" etc would be providers.  
> In your action you need to define your logic (iterating over all your files and calling the standard link provider do perform the actual link).
> 
> Read up on LWRPs in the wiki, or just look at the existing providers in the chef gem.
> 
> For an example of passing a block and calling it, see [https://github.com/opscode/chef/blob/master/chef/lib/chef/resource/ruby\_block.rb](https://github.com/opscode/chef/blob/master/chef/lib/chef/resource/ruby_block.rb) and the matching [https://github.com/opscode/chef/blob/master/chef/lib/chef/provider/ruby\_block.rb](https://github.com/opscode/chef/blob/master/chef/lib/chef/provider/ruby_block.rb)
> 
> Andrea
> 
> On Oct 28, 2011, at 7:17 PM, Peter Norton [pn+chef-list@knewton.com](mailto:pn+chef-list@knewton.com) wrote:
> 
> > I'm migrating installations over to chef that currently do a lot of  
> > symlinking. The actual symlinks make sense, but don't adhere to the  
> > rails/capistrano layout deployed in the chef documentation for the  
> > deploy mechanism. It seems to me that the deploy mechanism is more  
> > than I want - I'd like to be able to do
> > 
> > symlink\_dir "foo" do  
> > user myuser  
> > group mygroup  
> > obj\_types ['d', 'l', 'f']  
> > source /source/filesystem/path  
> > dest /destination/filesystem/path  
> > end
> > 
> > and have all files, directories, and symlinks be symlinked from  
> > src-\>dst. Instead it seems that I have to do this:
> > 
> > bash "create\_bin\_symlinks" do
> > 
> > # Binary symlinks don't get directories linked in.
> > 
> > user 'user'  
> > group 'group'  
> > cwd dst\_dir  
> > code \<\<-EOBASH  
> > for item in $(ls #{src\_dir}) ; do  
> > if [-x #{src\_dir}/$item] && [! -d #{src\_dir}/$item] ; then  
> > [-h #{dst\_dir}/$item] || ln -s #{src\_dir}/$item #{dst\_dir}/  
> > fi  
> > done  
> > EOBASH  
> > end
> > 
> > and tailor this a bit for each file type that I want, which means I'll  
> > be littering a dozen cookbooks and 3x that recipes with this sort of  
> > thing.
> > 
> > How could I add to the DSL to create the feature I described here? In  
> > fact, how could I do it such that the obj\_types could be augmented by  
> > passing in a callback to a filter function so instead of just types I  
> > could use any property of the file to determine whether or not to make  
> > the symlink in the source and dest?
> > 
> > Thanks,
> > 
> > -Peter
