Skip to content

Commit 37d460c

Browse files
authored
Merge pull request #8825 from joshcooper/settings_docs
(maint) Add settings docs
2 parents 26307f0 + 9604207 commit 37d460c

File tree

2 files changed

+226
-0
lines changed

2 files changed

+226
-0
lines changed

docs/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,4 @@ Developer References
1616
* [Indirector](indirector.md)
1717
* [HTTP](http.md)
1818
* [Environment Convergence](environment_convergence.md)
19+
* [Settings](settings.md)

docs/settings.md

Lines changed: 225 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,225 @@
1+
Settings
2+
========
3+
4+
<!-- markdown-toc start - Don't edit this section. Run M-x markdown-toc-refresh-toc -->
5+
**Table of Contents**
6+
7+
- [Definitions](#definitions)
8+
- [Sections](#sections)
9+
- [Initialization](#initialization)
10+
- [Dashes & Underscores](#dashes--underscores)
11+
- [Setting Types](#setting-types)
12+
- [Setting Values](#setting-values)
13+
- [Duration & TTL Settings](#duration--ttl-settings)
14+
- [File/Directory Settings](#filedirectory-settings)
15+
- [Hooks](#hooks)
16+
- [Run Mode](#run-mode)
17+
- [Preferred Run Mode](#preferred-run-mode)
18+
- [Precedence](#precedence)
19+
- [File Watcher](#file-watcher)
20+
- [RSpec](#rspec)
21+
22+
<!-- markdown-toc end -->
23+
24+
Puppet can be configured via settings. All settings are defined in
25+
`lib/puppet/defaults.rb`. All settings have a type, value, description, etc.
26+
Settings can come from multiple sources such as the command line, configuration
27+
file, programmatically, etc, and are looked up in a specific order, so that the
28+
command line takes precedence over what's specified in puppet.conf.
29+
30+
Puppet settings can be looked up using `Puppet[:name]` and set using
31+
`Puppet[:name] = 'value'`.
32+
33+
# Definitions
34+
35+
Settings are defined using `Puppet::Settings#define_settings`. The method takes
36+
a section name, setting name and a hash describing the setting, e.g. its type,
37+
description, etc.
38+
39+
# Sections
40+
41+
Puppet settings can be specified in INI file format based on a section, for example:
42+
43+
```inifile
44+
[main]
45+
strict=true
46+
```
47+
48+
Comments and whitespace are ignored. A setting may be configured in any section,
49+
even if it wasn't defined in that section. For example, the `strict` setting is
50+
defined in `main`:
51+
52+
```ruby
53+
settings.define_setting(:main, strict: { ... })
54+
```
55+
56+
But it can be configured in any section, so this is legal:
57+
58+
```inifile
59+
[server]
60+
strict = true
61+
```
62+
63+
The purpose of the section name is when applying a settings catalog, see
64+
'File/Directory Settings' below.
65+
66+
Puppet predefines section names like `main`, `user`, `agent` and `server`. Only
67+
these sections are allowed in `puppet.conf`.
68+
69+
# Initialization
70+
71+
The entry point for initializing settings is `Puppet.initialize_settings`. It is
72+
possible to pass in command line arguments, as well as inject dependencies, such
73+
as an alternate facter implementation.
74+
75+
Puppet initializes its settings in three phases: global options, loading its
76+
`puppet.conf`, and application options.
77+
78+
First, puppet parses command line arguments using our vendored trollop library.
79+
Any argument with the same name as a puppet setting is automatically set. The
80+
argument and its optional value are "consumed" and unknown arguments are
81+
ignored. Puppet handles boolean arguments specially, so it's possible to pass
82+
`--onetime` or `--no-onetime`, and puppet will set the value to `true` or
83+
`false`, respectively.
84+
85+
Second, puppet loads `puppet.conf` from a predefined location depending on
86+
whether it's running privileged or not. See
87+
[https://github.com/puppetlabs/puppet-specifications/blob/master/file_paths.md](https://github.com/puppetlabs/puppet-specifications/blob/master/file_paths.md
88+
). Assuming puppet is running an application like `puppet agent`, then
89+
the application parses unconsumed arguments using Ruby's builtin
90+
`OptionParser`.
91+
92+
Third, the application parses any application-specific options using the same
93+
`OptionParser` instance from above. If the application defines an option with
94+
the same name as a setting, the application's option handler will be called
95+
last, so it "wins".
96+
97+
# Dashes & Underscores
98+
99+
Puppet settings are always defined using underscores, but application options
100+
should always be defined using dashes, e.g. `option("--job-id ID")`
101+
102+
As long as you're using Ruby 2.5 or above, `OptionParser` will automatically
103+
convert underscores to dashes, so your option handler will always be called
104+
even if the setting is specified using underscores in `puppet.conf` or on the
105+
command line.
106+
107+
# Setting Types
108+
109+
By default, settings are assumed to contain a string value. It is possible to
110+
specify another type when the setting is defined, such as `:type => :integer`. Each
111+
type maps to a subclass of `Puppet::Settings::BaseSetting`. In general, try to
112+
reuse an existing type instead of creating one subclass for every setting.
113+
114+
When creating a new setting type, you may need to implement the `munge` method
115+
to convert the external representation (the string "42") to its internal
116+
representation (the integer 42).
117+
118+
You may also want to implement the `print` method, which is invoked when running
119+
`puppet config print <name>`.
120+
121+
# Setting Values
122+
123+
Puppet defines several "root" settings that must be defined, such as `confdir`.
124+
These settings default to directories based on whether puppet is running as a
125+
privileged user and is running on Windows or not.
126+
127+
Non-root settings may be defined in terms of other settings. For example, the
128+
`ssldir` setting's value is defined to be `"$confdir/ssl"`. So in order to
129+
resolve the value of the `ssldir`, puppet will recursively resolve `confdir`.
130+
Puppet supports multiple levels of recursion, but will raise if it detects a
131+
cycle.
132+
133+
## Duration & TTL Settings
134+
135+
Puppet's duration and ttl-based settings assume the value is specified in
136+
seconds unless units are specified, such as `5m`, `1h`, etc.
137+
138+
## File/Directory Settings
139+
140+
The `file` and `directory` settings are handled specially, because puppet will
141+
compile an internal "settings" catalog and apply it, to ensure they match the
142+
desired state. So whenever `Puppet.settings.use(:main, etc)` is called, then all
143+
file and directory-based settings in the `main`, etc sections will be added to
144+
the settings catalog.
145+
146+
It is possible to specify the `owner` and/or `group` for these types of
147+
settings. The special `service` account means use whatever user/group puppet is
148+
configured to run under, as specified as `Puppet[:user]`/`Puppet[:group]`. For
149+
example, when puppet is a library within puppetserver, `Puppet[:user]` is set
150+
to the `puppet` user. This way puppetserver, not running as root, can access
151+
files that puppet creates.
152+
153+
It is also possible for a user to specify `owner`, `group` or `mode` metadata in
154+
`puppet.conf` by appending a hash after the value:
155+
156+
```inifile
157+
ssldir = "$confdir/ssl" { owner=root,group=root,mode=0750 }
158+
```
159+
160+
See also the `settings_catalog` and `manage_internal_file_permissions` settings,
161+
which can disable these behaviors.
162+
163+
# Hooks
164+
165+
It is possible to add a hook to a setting. The hook will be called at various
166+
times whenever the value is set. The hook may be called multiple times. Hook
167+
behavior is confusing and surprising! If you must define a new hook, use
168+
`on_initialize_and_write`. The other types of hooks won't be called if the
169+
setting is defined in a section that doesn't match the current run_mode.
170+
171+
If a setting's default value interpolates another base setting, then the hook
172+
will **not** be called if the base setting changes. So try to avoid mixing hooks
173+
and interpolated default values.
174+
175+
# Run Mode
176+
177+
Puppet can be configured to run in different "modes". The default run mode is
178+
`:user`, but can be switched to `:agent` or `:server`. If the run mode is
179+
switched, then it changes how settings are resolved. For example, given
180+
`puppet.conf` containing:
181+
182+
```inifile
183+
[server]
184+
node_terminus=exec
185+
```
186+
Then calling `Puppet[:node_terminus]` will return either `nil` or `exec`
187+
depending on the current run mode.
188+
189+
## Preferred Run Mode
190+
191+
Settings and run mode have a circular dependency. We need to know the run mode
192+
in order to load settings. However, puppet applications are defined in modules.
193+
So we need to resolve the `modulepath` setting to find the application, and then
194+
the application can change the run mode.
195+
196+
To break the dependency, puppet's preferred run mode is the mode it initially
197+
starts in, though it may change later on.
198+
199+
# Precedence
200+
201+
Puppet settings can be defined in multiple sources (command line, puppet.conf,
202+
etc). When looking up a value, puppet searches based on the precedence of each
203+
source, roughly in order of high to low:
204+
205+
* memory
206+
* command line
207+
* current environment.conf
208+
* section for the current run mode
209+
* main section
210+
* defaults
211+
212+
It is important to note that both the current environment and run mode change
213+
how the value is resolved.
214+
215+
# File Watcher
216+
217+
When running as a daemon, puppet will watch its `puppet.conf` and reload its
218+
configuration if it changes.
219+
220+
# RSpec
221+
222+
To avoid order-dependent test failures, puppet's rspec tests create unique
223+
"root" directories for each rspec example. For example, you can safely mutate
224+
settings in a test `Puppet[:strict] = true` or modify the contents of the
225+
`confdir` without affecting other tests.

0 commit comments

Comments
 (0)