7

I have access to just a module for our team, where as the global manifests are maintained by infrastructure team. The PATH variable gets set in the global manifests.

I want to append to the PATH variable, but puppet ignores my exec block.

file { "/etc/profile.d/set_java_home.sh":
    ensure => file,
    source => "puppet:///modules/teamXXX/set_java_home.sh",
    mode => "u=rw,go=r"
}

Exec { path => [ "\${PATH}", "\${JAVA_HOME}/bin" ] }

How can I append to the PATH variable?

edit

I should have mentioned, I am looking to enhance the PATH variable for users's shell environment, rather than puppet's execution environment.

manish
  • 315
  • 1
  • 3
  • 9

3 Answers3

7

Puppet cannot change the environment of the running shell. No subprocess can - the environment is copied to each child process, which then only has access to its individual copy.

To append something to the PATH of all new login shells, you need to change the profile configuration file. If you're using a recent version of bash, there should be a /etc/profile.d. You can use a resource like this:

file { '/etc/profile.d/append-java-path.sh':
    mode    => '644',
    content => 'PATH=$PATH:/my/java/home/bin',
}
The Doge Prince
  • 458
  • 1
  • 7
  • 15
Felix Frank
  • 8,125
  • 1
  • 23
  • 30
  • thanks.. this solved my problem. I was under the impression that puppet might have a declarative resource type to set paths – manish Aug 15 '14 at 19:30
  • @manish apparently there is such a type for Windows (`windows_path`). For *NIX, this cannot work, because there is no system wide path setting. – Felix Frank Aug 16 '14 at 18:01
1

Three problems:

1) You cannot access local client environment variables like PATH and JAVA_HOME unless you have a facter script that injects them into your Puppet client environment. My guess is that you don't.

2) Exec blocks set up their own local environment that is destroyed at the end of the Exec block. So you can set the path in an Exec block all you want and it won't do a thing for the rest of your blocks. See provider/exec.rb in the Puppet source code.

3) Unless some other block has a before => Exec["my_exec_block"] in it, the Exec block will run in some arbitrary semi-random order, probably not when you want it to run.

Your best bet is to run the action as a script and set up the PATH inside the actual script. Thus:

file { "/opt/myapp/install_java_app":
      notify => Exec["install_java_app"],
      mode => 755,
      source => "puppet:///modules/myapp/install_java_app",
      before => Exec["install_java_app"]
    }
exec { "install_java_app" :
      path => "/usr/bin:/usr/sbin:/bin:/sbin:/opt/myapp",
      command => "install_java_app",
      refreshonly => true
    }

Then /opt/myapp/install_java_app would have any PATH assignments in it that you needed.

This is sort of clunky, but that's Puppet.

eric.green
  • 440
  • 3
  • 8
  • Wait, you mean a fact that alters the environment? So that the agent uses that instead? - If that works, it should be considered an awful hack. Well done :-) – Felix Frank Aug 12 '14 at 17:13
1

Here is an example of how to append to the path:

Exec { path => [ '/bin' ] }

exec { [ 'ls', 'who' ]: returns => 0; }

Exec[who] { path +> [ '/usr/bin' ] }

Sadly, the resource override cannot be circumventend - the +> syntax is only valid there.

I didn't double check wether this leads to a prepended path or appended (I'd assume the latter), so if that is of significance to you, you will want to double check.

Felix Frank
  • 8,125
  • 1
  • 23
  • 30
  • I should have mentioned, I am looking to enhance the PATH variable for users's shell environment, rather than puppet's execution environment. – manish Aug 15 '14 at 01:35
  • Yes. Yes, you should have. Added another answer with this context. – Felix Frank Aug 15 '14 at 11:24