summaryrefslogtreecommitdiffstats
path: root/documentation/languagetutorial.rst
diff options
context:
space:
mode:
authorluke <luke@980ebf18-57e1-0310-9a29-db15c13687c0>2006-06-07 18:14:00 +0000
committerluke <luke@980ebf18-57e1-0310-9a29-db15c13687c0>2006-06-07 18:14:00 +0000
commit1a93e6d6d8c253da985262f7adfeb533570ec17f (patch)
tree6de993ce4db8fa738ccff5255610d8a8a10bc7b6 /documentation/languagetutorial.rst
parentd84827e09510bd069f912fc3d1c30a38355a054a (diff)
copying all documentation from the plone site
git-svn-id: https://reductivelabs.com/svn/puppet/trunk@1237 980ebf18-57e1-0310-9a29-db15c13687c0
Diffstat (limited to 'documentation/languagetutorial.rst')
-rw-r--r--documentation/languagetutorial.rst150
1 files changed, 150 insertions, 0 deletions
diff --git a/documentation/languagetutorial.rst b/documentation/languagetutorial.rst
new file mode 100644
index 000000000..018eb4151
--- /dev/null
+++ b/documentation/languagetutorial.rst
@@ -0,0 +1,150 @@
+Elements and Organization
+=========================
+The entire purpose of the Puppet language is to result in Puppet elements that
+directly model elements on each client being managed. Because different
+clients have different lists of elements, and some clients vary in the
+configuration of specific elements, Puppet's language supports various
+abstraction, selection, and overriding capabilities.
+
+Naming
+=============
+For simple elements, we just specify the element type, name, and parameters::
+
+ file { "/etc/passwd":
+ owner => root,
+ group => root,
+ mode => 644
+ }
+
+Any machine on which this snippet is executed will use it to verify that the
+``passwd`` file is configured as specified. The Puppet language treats the
+field before the colon as the name of the object, so in this case the name is
+``/etc/passwd``, which works fine for this file since both the path and the
+details are essentially always the same on all systems.
+
+For files that vary across systems, it makes sense to create a *symbolic name*
+for your element::
+
+ file { sshdconfig:
+ path => $operatingsystem ? {
+ solaris => "/usr/local/etc/ssh/sshd_config",
+ default => "/etc/ssh/sshd_config"
+ },
+ owner => root,
+ group => root,
+ mode => 644
+ }
+
+Here we create a symbolic name instead of using the path as the name, and now
+we can refer to that element by name elsewhere in the manifest::
+
+ service { sshd:
+ subscribe => file[sshdconfig]
+ }
+
+This will cause the ``sshd`` service to get restarted when the ``sshdconfig``
+file changes.
+
+It's important to note here that the language doesn't actually know anything
+about the objects it is managing; it knows the name and the type, and it has a
+list of parameters, but those parameters mean nothing in the language. If you
+provide a symbolic name to a given element, you should always use that single
+name, because otherwise the language will assume you are managing separate
+elements, which might result in an error in the library::
+
+ file { sshdconfig:
+ path => "/usr/local/etc/ssh/sshd_config",
+ owner => root
+ }
+
+ file { "/usr/local/etc/ssh/sshd_config":
+ owner => sshd
+ }
+
+The Puppet parser does not know that these element specifications will attempt
+to manage the same element, because they have different names. This will
+result in an error on the client when the second element tries to instantiate
+and it is found to conflict with the first element.
+
+Assignment
+==========
+Puppet has a declarative language, which means that its scoping and assignment
+rules are somewhat different than a normal imperative language. The primary
+difference is that you cannot change the value of a variable within a single
+scope, because that would rely on file order to determine the value of the
+variable. This will result in an error::
+
+ $user = root
+ file { "/etc/passwd":
+ owner => $user
+ }
+ $user = bin
+ file { "/bin":
+ owner => $user,
+ recurse => true
+ }
+
+You will almost always find that you can avoid resetting variable values using
+the builtin conditionals_::
+
+ $group = $operatingsystem ? {
+ solaris => sysadmin,
+ default => wheel
+ }
+
+This is only one assignment, so no errors.
+
+Overriding
+==========
+Puppet provides a separate scope for every class and component, and scope
+trees are created as a manifest is parsed. Take the following configuration::
+
+ class base {
+ file { "/etc/issue":
+ source => "puppet://server/module/common/issue"
+ }
+ }
+
+ class sub inherits base {
+ file { "/etc/issue":
+ source => "puppet://server/module/mysite/issue"
+ }
+ }
+
+This creates two distinct scopes, one for each class. The ``sub`` class
+overrides the specification of ``/etc/issue``, because it's in a lower scope,
+and when this manifest is applied, the latter location is used as the source
+for the file. This allows you to subclass a class and slightly change its
+behaviour.
+
+Defaults
+========
+Puppet elements are normally specified using a lower-case element type. You
+can specify default values for a given type using the capitalized form of the
+element type, though::
+
+ Exec { path => "/usr/bin:/bin:/usr/sbin:/sbin" }
+
+ import "classes/*.pp"
+
+ node mynode {
+ include $operatingsystem
+ }
+
+The first statement in this snippet provides a default value for 'exec'
+elements, which require either fully qualified paths or a path in which to
+look for the executable. This way you can specify a single default path for
+your entire configuration, and then override that value as necessary.
+
+This can be used for any element type. For instance, CentOS defaults to using
+``rpm`` for its package type, but you can easily change that to ``yum``::
+
+ case $operatingsystem {
+ centos: {
+ Package { type => yum }
+ }
+ }
+
+ ...
+
+.. _conditionals: /projects/puppet/documentation/structures#conditionals