5

I want ~/.bashrc will be source whenever changing its content. I created a bashrc class with something like this:

file { "/root/.bashrc":
    ensure  => present,
    owner   => root,
    group   => root,
    mode    => 0644,
    source  => "puppet:///bashrc/root/.bashrc"
}

exec { "root_bashrc":
    command     => "source /root/.bashrc",
    subscribe   => File["/root/.bashrc"],
}

but as you know, source is a shell built-in command, thereforce I got the following error when running agent:

# puppet agent --no-daemonize --verbose
notice: Starting Puppet client version 2.7.1
info: Caching catalog for svr051-4170
info: Applying configuration version '1311563901'
err: /Stage[main]/Bashrc/Exec[root_bashrc]/returns: change from notrun to 0 failed: Could not find command 'source'
notice: Finished catalog run in 2.28 seconds
notice: Caught INT; calling stop

Is there any workaround to do this?

voretaq7
  • 79,345
  • 17
  • 128
  • 213
quanta
  • 50,327
  • 19
  • 152
  • 213
  • 2
    Please help us understand what you're asking for; do you mean that you want Puppet to include the contents of "/root/.bashrc" whenever it uses the `exec` resource to make changes? I think you need to add more details about what overall goal you're trying to accomplish; the way you're going now is probably not going to work. – Handyman5 Jul 25 '11 at 04:46
  • +1 for what handyman5 is saying – Mike Jul 25 '11 at 05:41
  • Sorry if my post is not clear enough. I mean I want to run `source ~/.bashrc` when its content is changed (just like when a configuration file is updated, you want to restart the corresponding service). – quanta Jul 25 '11 at 06:12
  • It doesn't makes sense to do that - you will need to restart the service that uses the environment anyway ( because it's environment is already loaded with the older bashrc ) – filipenf Apr 14 '14 at 16:19

3 Answers3

7

There's no point in re-sourceing a new .bashrc within Puppet, because it'll run in a subshell and the changes won't propagate into your current shell (which is, I assume, what you're trying to do). You can't do what (I think) you want to do.

womble
  • 95,029
  • 29
  • 173
  • 228
4

Technically, you could use:

exec { "root_bashrc":
    command     => "bash -c 'source /root/.bashrc'",
    subscribe   => File["/root/.bashrc"],
    refreshonly => true,
}

However, as @womble already pointed out, there's no point in sourcing .bashrc like that; it only affects the bash shell that's run in that command, not any currently running bash shells.

You could possibly set PROMPT_COMMAND="source /root/.bashrc" to rerun the .bashrc every time a prompt is displayed in any currently running interactive shells, but that seems a bit resource intensive. I've never tried this, but I'd think it would work.

freiheit
  • 14,334
  • 1
  • 46
  • 69
4

You can also often preface your command with true && or use provider => shell.

See this and this for additional discussion.

This should be:

file { "/root/.bashrc":
    ensure  => present,
    owner   => root,
    group   => root,
    mode    => 0644,
    source  => "puppet:///bashrc/root/.bashrc" }

exec { "root_bashrc":
    command     => "source /root/.bashrc",
    provider => shell,
    subscribe   => File["/root/.bashrc"], 
}
pcaceres
  • 119
  • 1
  • 4
  • 2
    `provider` => 'shell'` looks like the best answer by far. But remember that `sh` is not `bash` therefore we should use `.` instead of `source`. – Felipe Jun 19 '14 at 06:13
  • here is the actual issue that solved this, I think: http://projects.puppetlabs.com/issues/4288#note-23 – Felipe Jun 19 '14 at 06:14