summaryrefslogtreecommitdiffstats
path: root/documentation/introduction.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/introduction.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/introduction.page')
-rw-r--r--documentation/introduction.page313
1 files changed, 313 insertions, 0 deletions
diff --git a/documentation/introduction.page b/documentation/introduction.page
new file mode 100644
index 000000000..2d1cd680c
--- /dev/null
+++ b/documentation/introduction.page
@@ -0,0 +1,313 @@
+---
+inMenu: true
+---
+# Introduction
+
+Puppet is a system configuration tool. It has a library for managing the
+system, a language for specifying the configuration you want, and a set of
+clients and servers for communicating the configuration and other information.
+
+The library is entirely responsible for all action, and the language is
+entirely responsible for expressing configuration choices. Everything is
+developed so that the language operations can take place centrally on a single
+server (or bank of servers), and all library operations will take place on each
+individual client. Thus, there is a clear demarcation between language
+operations and library operations, as this document will mention.
+
+# Setup
+
+The vast majority of Puppet architectures will look like a star, with a
+central server running `puppetmasterd`, and each client node running
+`puppetd`, contacting that central server. Your central manifest, which
+contains the configuration for all of your nodes, needs to be on the central
+server, most likely at `/etc/puppet/manifests/site.pp`.
+
+Start the `puppetmasterd` daemon, and then tell your clients to contact that
+server by specifying `-s <servername>` as arguments to `puppetd`, replacing
+"<servername>" with the name of the server. Alternatively, `puppetd` defaults
+to looking for a server named "puppet", so you can just create a CNAME for
+your server, so that it answers to "puppet".
+
+It is a good idea to run both the server and client in verbose mode, enabled
+with the `-v` flag, until you are sure everything is working. As each new
+client connects, you will need to run `puppetca --list` to list the
+certificates waiting to be signed, and then `puppetca --sign <name>`,
+replacing "<name>" with the name of the client whose certificate you want to
+sign. You can turn on autosigning by creating `/etc/puppet/autosign.conf` and
+put the hosts, domains, or IP addresses or ranges that you want to sign in
+there.
+
+# Language
+
+The language is declarative, and is modeled somewhat after cfengine's concept
+of actions, action instances, and instance parameters. Here is how a file
+element would look in puppet:
+
+ file { "/etc/passwd":
+ owner => root,
+ group => root,
+ mode => 644
+ }
+
+Each instance of a low-level element like ``file`` must have a name parameter
+defined, because that is how you uniquely refer to the element you are
+managing. Any string that doesn't match ``\w+`` or ``\d+`` needs to be quoted
+(e.g., file names).
+
+There are two ways for types to be available in the language: They'll either
+be ``primitive types`` included in the Puppet framework itself, or they'll be
+``defined types`` resulting from definitions or server classes.
+
+## Definitions
+
+Because experience with cfengine showed that objects of different types are
+often related, puppet focuses on making creation of associations between
+objects of any type easier than making many objects of the same type. The
+fundamental unit of association is a 'definition':
+
+ # currently, the variables don't have '$' attached in the definition prototype
+ # this might change
+ define sudo(source,group) {
+ package { sudo:
+ version => "1.6.7"
+ }
+ file { "/etc/sudoers":
+ source => $source, # parameterization; copy the file from where?
+ mode => 440 # the 'file' type converts this appropriately to
+ # octal
+ }
+ file { "/usr/sbin/sudo":
+ owner => root,
+ group => $group
+ }
+ }
+
+A definition has its own scope, so variables defined within it are only
+available within the definition itself.
+
+This definition can now be treated as a type:
+
+ sudo {
+ group => root,
+ source => "http://fileserver/files/sudoers?v=production"
+ }
+
+One significant difference between definitions and types is that types
+generally have many associated parameters, most of which are optional, while a
+given definition will (at this point) always require all parameters. You can
+manage as little or as much of a file as you want, for instance, but once you
+wrap it in a definition you have to pass every specified parameter to instances
+of the definition.
+
+It is appropriate to think of definitions as declarative functions; referring
+to the name of a definition results in the associated declarative code being
+executed with the provided parameters.
+
+I will likely soon add the ability to provide defaults to definition
+parameters; any other feature requests are welcome.
+
+## Classes
+
+In addition to definitions, the language supports server classes. Classes are
+different from definitions in two fundamental ways: They do not (currently)
+support parameterization, and sub classes can override base classes.
+
+Classes can be called using the same syntax as definitions, although always
+without arguments and usually without names, but they are generally called
+with the ``include`` keyword, which is more flexible in that it supports
+variable interpolation and conditional expressions:
+
+ class base {
+ include sudo
+ }
+
+ class server inherits base {
+ include ssh
+ }
+
+ case $hostname {
+ myhost: { include server }
+ default: { include base }
+ }
+
+ include $operatingsystem
+
+
+## Variables
+
+Because it is assumed that strings will be used far more than variables, simple
+strings don't have be quoted or otherwise marked, but variables must have the
+``$`` attached:
+
+ $group = "root"
+
+ file { "/etc/sudoers":
+ group => $group
+ }
+
+Strings and booleans (``true`` and ``false``) are the only data types; even
+numbers are converted to strings. Arrays are supported, although their
+behaviour has not been characterized for all cases. One particular use of
+arrays is for implicit iteration:
+
+ $files = ["/etc/passwd","/etc/group","/etc/fstab"]
+
+ file { $files:
+ owner => root,
+ group => root
+ }
+
+This implicitly iterates across the file list and performs all of the
+appropriate checks.
+
+Currently, ``puppet`` collects as much information as it can (using the
+``Facter`` library) and sets all of it as top-level variables. So, you can
+expect variables like ``$operatingsystem`` and ``$ipaddress``.
+
+Also, because ``puppet`` is a declarative language, reassigning a variable
+within the same scope is currently an error. The language is written such that
+this could be disabled (please let me know if you need this feature), but it is
+currently always enabled. You can override defaults in a lower scope:
+
+ $var = default
+
+ define test {
+ $var = override
+ ...
+ }
+
+It is expected that parameter passing to definitions will be the primary
+mechanism for variable assignment, so it seems unlikely that this limitation
+will cause much trouble.
+
+## Importing
+
+Files can be imported using the ``import`` command:
+
+ import "filename"
+
+There is currently no search path or anything; files are looked for in the same
+directory as the file doing the importing. Each file should have its own
+lexical scope, but I haven't yet figured out how to do that.
+
+## Control Structures
+
+There are currently two basic control structures, one meant to return a value
+and the other just a normal 'if/elsif/else' structure.
+
+### Selectors
+
+One of the primary goals of Puppet is to simplify building a single
+configuration that works across multiple machines and machine classes. One
+mechanism for this is currently called a 'selector'; it is similar to the
+trinary operator ``:?``:
+
+ $value = $variable ? {
+ value1 => setvalue1,
+ value2 => setvalue2,
+ default => other
+ }
+
+This sets the variable ``$value`` depending on the value of ``$variable``. If
+it is ``value1``, then ``$value`` gets set to ``setvalue1``, else the value
+gets set to ``other``.
+
+The brackets can be in either part of the expression, or not at all:
+
+ $value = $variable ? "value1" => "setvalue1"
+
+A selector that doesn't match a value is a compile error.
+
+These structures are useful for simplistic abstraction across platforms:
+
+ file { "/etc/sudoers":
+ owner => root,
+ group => $operatingsystem ? {
+ SunOS => root,
+ Linux => root,
+ FreeBSD => wheel
+ }
+ }
+
+Selectors can specify default values using the ``default`` keyword.
+
+### Case Statements
+
+Puppet currently supports a normal Case structure similar to so many other
+languages:
+
+ case $operatingsystem {
+ solaris: { include sunos }
+ debian: { include linux }
+ default: { include $operatingsystem }
+ }
+
+As you can see, case statements also support defaults.
+
+The difference between the case stateements and the selectors is that the
+selectors just return values while the case statements execute arbitrary
+Puppet code.
+
+# Library
+
+This section discusses some aspects of the internals of the Puppet library.
+This information can be useful but is not critical for use and understanding
+of Puppet.
+
+The library is composed of two fundamental types of objects: Types and states
+(yes, the terminology is atrocious). States are things that can be configured
+to change one aspect of an object (e.g., a file's owner), types are essentially
+named collections of states. So, there is a File type, and it is a collection
+of all of the states available to modify files.
+
+In addition to states, which necessarily modify 'the bits on disk', as it were,
+types can also have non-state parameters which modify how that type instance
+behaves:
+
+ file { "/bin":
+ owner => bin,
+ recurse => true
+ }
+
+The ``recurse`` parameter to ``file`` does not modify the system itself, it
+modifies how the ``file`` type manages ``/bin``.
+
+Not all types as expressed in the language are types defined in the library;
+some language types are actually definitions or server classes. Types that
+are defined in the language itself are termed ``primitive types`` or just
+``primitives``, and types that generate other types are termed ``metatypes``.
+
+At this point, all types have a unique name (within the current scope, but it
+probably should actually be global). This name is set using a class instance
+variable: :
+
+ # in the library
+ Puppet::Type.newtype(:mytype)
+ ...
+ end
+
+ # in the language
+ mytype { "yay": ... }
+
+The states similarly have unique names, although this uniqueness is only
+per-type. When a type is defined, all states and parameters are added using
+class methods. Here is the File type declaration:
+
+ newstate(:ensure) do ... end
+ newstate(:owner) do ... end
+ newstate(:group) do ... end
+ ...
+ newparam(:path) do ... end
+
+Lastly, each type must either provide a state or parameter of ':name', or it
+must mark a parameter as the namevar so that the system knows what is
+considered the name:
+
+ newparam(:path) do
+ isnamevar
+ end
+
+With this declaration, ``file { "/tmp/file": }`` is basically equivalent to ``file { path => "/tmp/file" }``.
+
+See [Creating a Puppet Type](creating-a-puppet-type.html) for more
+information.