summaryrefslogtreecommitdiffstats
path: root/documentation/languagetutorial.page
diff options
context:
space:
mode:
authorluke <luke@980ebf18-57e1-0310-9a29-db15c13687c0>2006-06-17 01:56:04 +0000
committerluke <luke@980ebf18-57e1-0310-9a29-db15c13687c0>2006-06-17 01:56:04 +0000
commit644fd4e5ff3cf3a31370be48c7d960e74204477d (patch)
tree98619c04b07ac461935505abc95ac2d533e10108 /documentation/languagetutorial.page
parentf0907607347c26127dd566fbe5b19c8528d25f5d (diff)
downloadpuppet-644fd4e5ff3cf3a31370be48c7d960e74204477d.tar.gz
puppet-644fd4e5ff3cf3a31370be48c7d960e74204477d.tar.xz
puppet-644fd4e5ff3cf3a31370be48c7d960e74204477d.zip
updating docs to work with webgen
git-svn-id: https://reductivelabs.com/svn/puppet/trunk@1293 980ebf18-57e1-0310-9a29-db15c13687c0
Diffstat (limited to 'documentation/languagetutorial.page')
-rw-r--r--documentation/languagetutorial.page153
1 files changed, 153 insertions, 0 deletions
diff --git a/documentation/languagetutorial.page b/documentation/languagetutorial.page
new file mode 100644
index 000000000..3ea7ca1b4
--- /dev/null
+++ b/documentation/languagetutorial.page
@@ -0,0 +1,153 @@
+---
+inMenu: true
+title: Language Tutorial
+---
+
+# 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](structures.html#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 }
+ }
+ }
+
+ ...