Tuesday, April 8, 2014

puppet create directory recursively

The whole VERY OLD rant is here  http://projects.puppetlabs.com/issues/86
Why on earth in 8 years the Puppet Gods have kept ignoring this very basic and common need, they only know.

In a nutshell, I have a variable
file { "$mypath":
   ensure => directory,
   owner => 'soa'

This will of course fail if /opt and /opt/oracle have not been already defined.

Of course since $mypath is a configuration value there is  no way I can hardcode all the parents directories.

Hence I am screwed, and Puppet doesn't offer me any way around.

I can think of only one elegant way, that is writing a Ruby function (I am not good in Puppet stinky DSL) "pathExpand" to transform a full path into an array of his components:

assert [ '/opt', '/opt/oracle', '/opt/oracle/fmw11_1_1_6' ] = pathExpand('/opt/oracle/fmw11_1_1_6')

and a define "conditionalDirectory($mypath ):

if (! defined($mypath)) {
  file { "$mypath":
    ensure => directory,

All this sucks, but not as much as Puppet DSL anyway.

This is a Puppet solution (hack) to the problem:

define common::mkdirp(
  $owner     = 'root',
  $group     = 'root',
  $exec_path = '/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin') {

  exec { "create ${name}":
    command     => "mkdir -p ${name}",
    creates     => $name,
    path        => $exec_path,

  common::ownership { $name:
    user        => $owner,
    group       => $group,
    exec_path   => $exec_path,
    require     => Exec["create ${name}"]


define common::ownership(
  $group     = undef,
  $dir       = $name,
  $exec_path = '/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin'
) {

  $real_group = $group ? {
    undef   => $user,
    default => $group

  exec { "full '${dir}' directory ownership for ${user}:${real_group}":
    path    => $exec_path,
    command => "chown -R ${user}:${real_group} ${dir}",
    unless  => "test `find ${dir} -user ${user} -group ${real_group} | wc -l` -eq `find ${dir} | wc -l`",


No comments: