1

I am using Puppet to manage the configurations of some servers. One of the tasks is to create a specific folder structure under /www for hosting our applications.

But lately, we've had this server where /www is just a symbolic link to another directory (had to do that because of storage shortage)

$ ls -l /www
lrwxrwxrwx 1 root root 13 Oct 25 15:33 /www -> /storage/www/

And we've been using this so far to manage directories:

file { $path:
ensure => directory,
owner  => user,
group  => group,
mode   => 'a=rx,u+w'
}

The issue with this specific server, is that when running Puppet, the /www symlink gets deleted and Puppet creates a new regular directory under /www instead. And that breaks the applications for us unless we intervene manually to create the symbolic link again.

My question: Does someone know of a way that makes Puppet not delete the symlink and just treat it as a directory: If no /www directory or no /www symlink exists, create the /www directory, else do nothing?

2

The short answer is to change

file { $path:
    ensure => directory,
    owner  => user,
    group  => group,
    mode   => 'a=rx,u+w'
}

into

file { $path:
    ensure => link,
    target => /path/to/original/directory
    owner  => user,
    group  => group,
    mode   => 'a=rx,u+w'
}

By using ensure => directory, you are telling puppet that you want a directory, and that anything else it finds (like a file or symbolic link) it should clobber and replace with the directory. By using ensure => link, you'll be telling puppet that you want a symbolic link that points to the value of target, which in turn could be a directory, a file, or a device. Depending on what you're doing, you may need to create a file type (using ensure => directory) on your target, if you need puppet to manage it.

I would strongly recommend you read the documentation for the file type to better understand how to use it.

Edit:

To distinguish between different servers, you'll want to use individual node definitions for your different servers. You could essentially do the following to get what you want:

node 'server1.mydomain.com' {
    file { $path:
        ensure => directory,
        owner  => user,
        group  => group,
        mode   => 'a=rx,u+w'
    }
}

node 'server2.mydomain.com' {
    file { $path:
        ensure => link,
        target => /path/to/original/directory
        owner  => user,
        group  => group,
        mode   => 'a=rx,u+w'
    }
}
  • I don't want to have symbolic link on all the servers, The problem is, /www is not always a symbolic link. On some servers, it's a regular directory, on others it's a symbolic link. Sometimes it does not exist at all and needs to be created. – Mehdi Yedes Oct 26 '16 at 14:53
  • The thing about puppet is that essentially its a state machine. You could create separate configurations for each server, but that adds a level of complexity that you will always have to maintain. One or two "exceptions" may not seem like much, but at some point a line has to be drawn. – dohpaz42 Oct 26 '16 at 14:55
  • 1
    @midihenry, I've updated my answer to address your concern. – dohpaz42 Oct 26 '16 at 15:08
  • Thanks, that might be a workaround in this case. But that does not really answer my question. So as far as I understand, there is no option in Puppet to just consider symbolic links to directories as directories. Just found this issue that describes my problem: projects.puppetlabs.com/issues/4394 – Mehdi Yedes Oct 26 '16 at 15:27
  • You could do it with a single file { $path : ...} just use a variable for the ensure value that is set in the node/hiera/other. – Zoredache Oct 26 '16 at 16:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.