creating file locations from hiera

803 views
Skip to first unread message

Peter De Cleyn

unread,
Jan 25, 2013, 9:25:34 AM1/25/13
to puppet...@googlegroups.com
Hi list,

I ran again against a long standing bug / feature request but from a new angle: creating directories with parents  (http://projects.puppetlabs.com/issues/86).

I wanted to create a module, where a path could be supplied with a class parameter. The path would be used in a rsync configuration, so I would like to be sure the path exists. As I want the module to be general and completely separate code and data, I didn't want to configure a "base path" in which all rsync modules would need to live. But there is AFAIK no "mkdir -p" alternative in puppet, unless I'd go with an ugly exec.

Any ideas houw to realise this? I probably could define my path in hiera as an hash and as such define all parent folders, but this is not that elegant.

Peter

Brian Lalor

unread,
Feb 1, 2013, 6:57:50 AM2/1/13
to puppet...@googlegroups.com
On Jan 25, 2013, at 9:25 AM, Peter De Cleyn <pe...@decleyn.net> wrote:

I ran again against a long standing bug / feature request but from a new angle: creating directories with parents  (http://projects.puppetlabs.com/issues/86).

I was blown away when I saw that issue.  It's been open for 7 years and nobody can figure out how to create a directory tree?  It's kinda mind-boggling.

I wanted to create a module, where a path could be supplied with a class parameter. The path would be used in a rsync configuration, so I would like to be sure the path exists. As I want the module to be general and completely separate code and data, I didn't want to configure a "base path" in which all rsync modules would need to live. But there is AFAIK no "mkdir -p" alternative in puppet, unless I'd go with an ugly exec.

Any ideas houw to realise this? I probably could define my path in hiera as an hash and as such define all parent folders, but this is not that elegant.

Short of writing a plugin, I do think the exec is your best bet.  It's ugly but effective.

jcbollinger

unread,
Feb 4, 2013, 10:38:15 AM2/4/13
to puppet...@googlegroups.com


On Friday, February 1, 2013 5:57:50 AM UTC-6, blalor wrote:
On Jan 25, 2013, at 9:25 AM, Peter De Cleyn <pe...@decleyn.net> wrote:

I ran again against a long standing bug / feature request but from a new angle: creating directories with parents  (http://projects.puppetlabs.com/issues/86).

I was blown away when I saw that issue.  It's been open for 7 years and nobody can figure out how to create a directory tree?  It's kinda mind-boggling.



The issue is not about how to create a directory tree, of course.  It's about what resources Puppet is actually managing, and what their properties are.  If I write

file { '/path/to/myfile':
  ensure => 'file',
  content => '#not empty',
  uid => 'someone',
  gid => 'agroup',
  mode => '0644',
  create_parents => true
}

then what managed resource(s) does it actually declare?  Certainly it declares File['/path/to/myfile'], but does it also declare File['/path/to'] and File['/path']?  If so, then what properties are declared for them?  What if they are also declared elsewhere?  Is its meaning different when the parent directory exists than when it doesn't?

I may not have said this in a while, and it bears repeating: Puppet is not a script engine.  Rather, it is a state management service, and as such it is essential that the target state to which nodes are managed be clear, and that it be consistent for consistent manifests, facts, and server-side data.  The point, then, is not that the above questions cannot be answered, but rather that there isn't a satisfactory set of answers.

In any case, you can roll your own relatively easily to get something that suits your particular desire-of-the-moment.  For example, here's a reusable definition that wraps an ordinary File resource with parent auto-creation:

define mymodule::file_with_parent (
    $ensure => 'present',
    $uid => undef,
    $gid => undef,
    $mode => undef,
    $content => undef
    # ...
  ) {

  file { $name:
    ensure => $ensure,
    uid => $uid,
    gid => $gid,
    mode => $mode,
    content => $content
    # ...
  }

  $parent = regsubst($name, '/[^/]*/?$', '')
  if ($parent != $name) and ($parent != '') {
    exec { "create parent directory $parent":
      # mode? uid/gid?  you decide...
      command => "/bin/mkdir -p $parent",
      creates => "$parent",
      before => File[$name]
    }
  }
}

That will probably give you parent directories owned by root if the agent has to create them, with permissions governed by whatever file mode creation mask is in effect for the agent.  Don't complain if you happen to get root/root/0700 (because if you're doing it this way then you don't care).

I wanted to create a module, where a path could be supplied with a class parameter. The path would be used in a rsync configuration, so I would like to be sure the path exists. As I want the module to be general and completely separate code and data, I didn't want to configure a "base path" in which all rsync modules would need to live. But there is AFAIK no "mkdir -p" alternative in puppet, unless I'd go with an ugly exec.

Any ideas houw to realise this? I probably could define my path in hiera as an hash and as such define all parent folders, but this is not that elegant.

The real problem here is not with the absence of built-in parent directory auto-creation in Puppet, it is with the module design.  It should not be the module's responsibility to create the entire parent directory tree, at least not without more information than the path to the rsync target directory.  Configurability and proper scoping are essential aspects of being "general", as the OP desired his module to be.  There are several ways the problem could be approached that neither rely on Execs nor require a module-wide base path, but they all require more data.


John

Reply all
Reply to author
Forward
0 new messages