|
In Unix, a process's environment is a set of key-value pairs made available to the process.Often, programs expect their environment to contain information required for the program to run. The details of how these key-value pairs are accessed depends on the API of the language being used.This article explains how environments of child processes interact with their parent process and how you can use Chef to ensure that services and applications are started with the proper environment. Child Processes and InheritanceChild processes inherit a copy of their parent's environment. In Bash (and other shells) the environment is accessible via shell variables. Shell variables can be added to the environment that is inherited by children processes using the export keyword. Consider the following example: As mentioned, the child process gets a copy of its parent's environment. This means that any changes made to that environment do not affect the parent process. For example: The principles mentioned above (a child process receives a copy of its parent's environment and cannot affect their parent's environment) apply in Ruby and Chef just as they do in Bash. In Ruby (and thus Chef), the current environment can be altered via the ENV variable. Any changes made to the environment will also be available to child process started by Chef. For example, consider the following recipe: When run, the bash resource will correctly echo "bar" to its standard output. However, just as in Bash, changes made in child processes have no affect on the parent, and thus no affect on subsequent child processes: When run, the second bash resource will not cause anything to be echoed to standard out as BAZ is not part of its environment. Managing Environments when Using ChefServices and other processes often look to environment variables for important information needed at run time. There are a number of ways to ensure that processes have access to the environment variables they need to run properly. Using the Service's Init ScriptIdeally, a service's init script would contain everything needed to properly start that service, including the necessary environment. Ensuring that the init script itself contains the necessary environment changes ensures that the service will start properly whenever it is being started using its init script, whether that be from Chef's service resource or directly from the shell. In classic System V init scripts, the environment can be altered just as it can be altered in any other shell script, by using a shell variable marked with the export keyword: Upstart ServicesFor services started using Upstart (the System V-compatible init system used by recent versions of Ubuntu and other distributions), their environment can be altered using env: See init(5) (provided with the upstart package) for more information. Systemd ServicesFor services started using systemd (the System V-compatible init system by the recent versions of Fedora and other distributions), their environment can be altered using the Environment or EnvironmentFile options: See systemd.exec(5) for more details. If the init script provided by the package does not include the necessary environment variables, you can manage your altered init script using Chef's template resource. Using ENVAnother method is to use Ruby's predefined ENV variable to set the environment variable. This ensures that any child processes (including the service that a resource may be starting) have this value in their environment. While not technically a Hash, ENV can be manipulated as if it were a Hash. For example: Note, however, that changes made to ENV only effect the environment of the chef-client process and its children processes. Altering the environment in this way will often ensure that Chef can start the service properly, but will not ensure that the service will start properly when started using other methods. Using Resource AttributesIf you are starting a processes by using an execute or script resource, you can use the environment attribute to alter the environment that will be passed to the process. Note that the only environment being altered is the environment being passed to the child process being started by the bash resource. This will not affect the environment of chef-client or subsequently started child processes. Other IssuesMy init script works fine when I'm logged in but not over ssh or when launched from chef-client running as daemon!Shells commonly alter their environment at startup by loading various initialization scripts. The files used for initialization vary based on whether the shell is started as an interactive or non-interactive shell and whether it is is started as a login or non-login shell. When you log in, you are likely starting an interactive, login shell. When you run a command via ssh, it is possible that you are starting a non-interactive shell. This can mean that the process in question is receiving different environments. Ensure that your service or process is being started in a way that ensures its environment has the necessary key-value pairs. I want to change the environment for every process!To change the environment for new processes, you will need to alter the initialization scripts for your system's shell. You can manage these scripts using a Chef template resource; however, there are a few caveats you should be aware of:
Additional ReadingOn most well configured unix-like systems, the following manual pages should be helpful:
|
|
|


