A puppet novice, I'm currently working on a deployment script that will start a couple of foreverjs services from rc.local at boot time.

My concern is that, in Ubuntu, rc.local comes with an exit 0 at the bottom of the file.

I don't see a way of using stdlib's file_line directive to ensure that my lines appear above the exit command (or anywhere else in particular, should the need arise).

I can do it with an exec block and some ugly sed, but there must be a more standard, elegant way in puppet?

  • 3
    Just distribute the whole file or use a template. – yoonix Mar 27 '14 at 17:45
  • Do you really need to deploy to rc.local? Can't you build your own init script? – Zoredache Mar 27 '14 at 18:19
  • @yoonix Indeed, my first thought was to just source the whole file, but I don't want to be destructive and overwrite content that might already be there (for whatever reason). The deployment environment is still, shall we say, fluid, so I'd like to leave as much wiggle room as possible. – msanford Mar 27 '14 at 18:56
  • @Zoredache Sorry, over-zealous editing: I accidentally deleted the line in my question where I explained that upstart won't work for this (for various silly reasons I am not in a position to fix). – msanford Mar 27 '14 at 19:07

You can use the PuppetLabs Concat module to dynamically insert parts into the rc.local file, like so:

Define the file as a concat file, and add a header (hash-bang, "managed by Puppet" comment, etc) - note the below may not work, I'm unsure of Puppet's newline handling off the top of my head!

concat { '/etc/rc.local':
  ensure => present,

concat::fragment { '00_rc.local_header':
  target  => '/etc/rc.local'
  content => '#!/bin/bash\n# This file is manageed by Puppet, do not modify!',
  order   => '01'

Add your custom parts, making sure to specify the correct target and an order value that is higher than your header:

concat::fragment { '05_rc.local_custom':
  target  => '/etc/rc.local',
  content => template('path/to/template.erb'),
  order   => '05'

concat::fragment { '15_rc.local_custom_2':
  target  => '/etc/rc.local',
  source  => 'puppet:///modules/mymodule/myfile.txt',
  order   => '06'

Add the exit 0 footer:

concat::fragment { '99_rc.local_footer':
  target  => '/etc/rc.local',
  content => 'exit 0\n',
  order   => '99'

Et fin!

You can use concat::fragment across multiple subclasses (and also multiple modules, though this really isn't recommended!) as long as you set the correct target value and you have that file declared as a concat resource. The order parameter allows you to position elements within the file.

Check the module's usage readme for more.

| improve this answer | |

If you have the cron service installed you can use it for this purpose by using the @reboot time specification. What makes this easier to manage with puppet is that you can just create a separate file in /etc/cron.d instead of trying to edit a single monolithic file.

I tested that the following works:

file { "/etc/cron.d/at_startup_myscript":
    content => "@reboot root /usr/local/bin/myscript.sh \n",
| improve this answer | |

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.