diff options
40 files changed, 13 insertions, 4061 deletions
diff --git a/documentation/documentation/about/glossary.page b/documentation/documentation/about/glossary.page deleted file mode 100644 index 79f3f9e4e..000000000 --- a/documentation/documentation/about/glossary.page +++ /dev/null @@ -1,47 +0,0 @@ ---- -inMenu: true -title: A Glossary of Terms -orderInfo: 3 ---- - -As developers have found time and time again, terminology is critical to -successful projects. The Puppet community has begun to coalesce around -certain terms found to be useful in working with Puppet: - -* **client**: An operating system instance managed by Puppet. This can be - an OS running on its own hardware or a virtual image. - -* **defined type**: A type written in Puppet's language. Also sometimes - called ``definitions`` or ``components``. - -* **manifest**: A configuration file written in the Puppet language. - -* **native type**: A type written purely in Ruby. - -* **provider**: A simple implementation of a type; examples of package - providers are ``dpkg`` and ``rpm``, and examples of user providers are - ``useradd`` and ``netinfo``. Most often, providers are just Ruby wrappers - around shell commands, and they are usually very short and thus easy to - create. - -* **resource**: An element to be managed on a client, such as a user, group, - or package. Resources do not always directly map to simple details on the - client -- they might sometimes involve spreading information across multiple - files, or even involve modifying devices. - -* **resource object**: A Puppet object in memory meant to manage a resource - on disk. Resource specifications get converted to these, and then they - are used to perform any necessary work. - -* **resource specification**: The details of how to manage a resource as - specified in Puppet code. When speaking about resources, it is sometimes - important to differentiate between the literal resource on disk and the - specification for how to manage that resource; most often, these are just - referred to as resources. - -* **type**: Also called ``resource type``. A class of resources that can be - managed. Types determine the modeling of the resources they are meant to - manage -- e.g., what attributes are valid, and what the valid values are for - those attributes. - -*$Id$* diff --git a/documentation/documentation/about/index.page b/documentation/documentation/about/index.page deleted file mode 100644 index f1480aa63..000000000 --- a/documentation/documentation/about/index.page +++ /dev/null @@ -1,15 +0,0 @@ ---- -inMenu: false -directoryName: About -title: About Puppet -orderInfo: 1 -subtreeLevel: 6 ---- - -About Puppet -===================== -* [Introduction](introduction.html) -* [Puppet vs. Cfengine](notcfengine.html) -* [Glossary](glossary.html) - -*$Id$* diff --git a/documentation/documentation/about/introduction.page b/documentation/documentation/about/introduction.page deleted file mode 100644 index 9f26456e5..000000000 --- a/documentation/documentation/about/introduction.page +++ /dev/null @@ -1,378 +0,0 @@ ---- -inMenu: true -title: Introduction -orderInfo: 10 ---- -# Introduction - -Puppet is a system configuration tool, generally meant to be used for -centralized, automated administration. It consists of a simple -specification language and a library of manageable resource types. The -language can be used to specify an entire network's configuration, and -the library can already manage most common rsources, like users, -packages, and services, and can be easily extended to support new types. - -The language and library are entirely decoupled; so decoupled, in fact, -that the language is usually compiled on a central server (called the -``puppetmaster``, of course), and the results are sent to each client, -which uses the library to apply the configuration. - -Puppet also includes a set of XMLRPC servers for communicating between -client and server. The primary server is used when a client connects to -the central server to have its configuration compiled, but there are -also servers for uploading reports, retrieving files, and quite a bit -more. - -Puppet is written entirely in Ruby, making it easy to maintain and fast -to develop. - -# 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`. Other than -creating this one file, Puppet is largely self-configuring. - -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``. - -All Puppet connections are via XMLRPC, encrypted with SSL certificates. -Because of how painful certificate management is, Puppet includes a -simple certificate authority that can generate client certificates, -along with a server for sending these certificates to the client. - -As you are setting up your Puppet install, 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, it -will send a certificate request to the server, which you will need to -sign. To do this, 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 influenced by cfengine's concept -of actions, action instances, and instance parameters (although in -Puppet we call these ``resources``). These resources are essentially -hashes with a type and title. For instance, here is how a file element -would look in puppet: - - file { "/etc/passwd": - owner => root, - group => root, - mode => 644 - } - -Puppet requires that each resource in your configuration be normalized -so that it is configured in only one place. The title of each resource -(``/etc/passwd``, in this case) is very important, because it is how -Puppet verifies that a given resource is unique. The occurrence of two -resources with the same type and title is a compile error. - -Puppet's language only supports strings and booleans (``true`` and -``false``), and quotes are optional for alphanumeric strings. - -## Resource Titles - -Naming can be somewhat confusing in Puppet, because every resource can -have two names. Each resource type has a parameter that's defined as -uniquely identifying the resource (usually called ``name``), but you can -specify a title in addition to the name. This is because many resources -that are effectively the same have names that vary on different systems. -You could just use a selector to handle this variance, but then you -would have to duplicate that selection every time you specified a -relationship to that resource. - -For instance, here is how OpenSSH might be specified: - - class ssh { - # Retrieve the configuration file - file { "/etc/ssh/sshd_config": - source => "/nfs/apps/ssh/sshd_config", - notify => Service[sshd] - } - - service { sshd: - name => $kernel ? { - linux => "sshd", - sunos => "openssh" - }, - ensure => running - } - } - -You can see that supporting two names here allows us to provide a -symbolic name that we can use consistently throughout our configuration. - -## 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 is *very* limited.. One particular use of arrays is for -creating many resources at once: - - $files = ["/etc/passwd","/etc/group","/etc/fstab"] - - file { ["/etc/passwd","/etc/group","/etc/fstab"]: - owner => root, - group => root - } - -This implicitly iterates across the file list and performs all of the -appropriate checks. - -Because ``puppet`` is a declarative language, reassigning a variable -within the same scope is a compile error. Puppet is currently -dynamically scoped, meaning that variables are inherited from calling -scopes, although this is expected to change at some point. - -## Client Facts and Facter - -Puppet clearly needs to know something about the client it is -configuring, so Puppet clients use the ``Facter`` library (an external -tool also maintained by Reductive Labs) to collect everything they can -about themselves and send that information to the server. The server -then defines these facts as variables in the top scope of the -configuration, so they are available throughout the configuration. This -is the case whether you are using Puppet in client/server mode or just -writing stand-alone Puppet scripts. - -You can run ``facter`` with no arguments to get a full list of available -facts on a given system. The most important facts are things like -``hostname`` and ``operatingsystem``, but many others are available, -including ``ipaddress`` and ``domain``. You can also define your own -facts very easily and have Puppet distribute them to your clients. - -## Definitions - -Puppet ships with many types written in Ruby as part of the main library -and it is straightforward to add new types, but the Puppet language -also allows you to define new resource types that are collections of -multiple resources. For instance, you could have a definition that -generates Apache virtual host configurations: - - # Versions prior to 0.19 did not support the "$" sigil in the - # prototype - define virtualhost($docroot) { - file { "/etc/apache2/sites-available/$name.conf" - content => template("vhost.erb"), - notify => Service[apache2] - } - } - -Note the use of the ``$name`` variable; this is equivalent to ``self`` -in many other languages; it is the value you provide before the colon -when you specify resources. Definitions are meant to be used multiple -times, so it is important that each resource contained within a -definition have a title that varies for each instance of the resource. -For instance, if you had a file with the title ``/my/file`` in a -definition, then each call to that definition would attempt to manage -that same file, which would be a compile error (again, because resources -must be normalized). - -The ``template`` function used above compiles an ERb template, allowing -you to use Puppet variables in the template, making it easy to generate -any files your clients need. Each definition has its own scope, so you -can define any variables you want and they will not be available outside -the definition. There are many other functions available, and it is -easy to add more. - -## Classes - -In addition to definitions, the language supports server classes. -Classes are meant to model server aspects, and as such they are -inherently singletons. This is one of the big differences between -classes and definitions -- classes can be included multiple times with -no harm. The other big difference is that classes support inheritance, -and subclasses can override resources defined in their parent classes. -For instance: - - class base { - file { "/etc/passwd": - owner => root, - group => root - } - } - - class freebsd inherits base { - File["/etc/passwd"] { group => wheel } - } - - case $operatingsystem { - freebsd: { include freebsd } - default: { include base } - } - -Notice that the syntax for overriding a resource is different than that -for initially specifying one. Prior to 0.20.0 the specification syntax -was used for both, and overriding was much more limited. - -## 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. Imports happen at -parse-time, so you cannot use variables in the name of the file being -imported. - -## Control Structures - -Puppet has limited control structures available, partially as an attempt -to remain declarative, but also partly because language development is -annoyingly difficult. - -### 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 a simple structure called a ``selector``; it is -similar to the trinary operator ``:?`` but supporting multiple values: - - $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. - -This structure will generally be the primary mechanism for supporting -multiple platforms or environments, since it makes it very easy to -select from a list of values. - -### 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 can contain -Puppet code. - -### If/Else - -Puppet also has a very limited ``if/else`` construct: - - if $server { - include webserver - } else { - include webclient - } - -The main limitation to the construct is that Puppet does not currently -support any comparison operators -- you can only test boolean values. - -# 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 organized around modeling resource types via modifyable -attributes. - -The library is composed of two fundamental types of objects: Types and -attributes. Attributes are things that can be configured to change one -aspect of an object (e.g., a file's owner), and types are essentially -named collections of attributes. So, there is a File type, and it is a -collection of all of the attributes available to modify files. - -Attributes are themselves divided into three different types: - -* **States** (horribly named, I know), which are the attributes that actually modify - the system (e.g., file owner, user home directory) -* **Parameters**, which only provide extra information to the states (e.g., - ``recurse`` on files, package sources) -* **MetaParameters**, which are valid for any resource type (e.g., - schedule, subscribe) - -## The Code - -Puppet has a simple mini-language for creating new types, with methods -for creating the types, their attributes, and then configuring -everything, such as adding validation or expressing innate relationships -between objects (e.g., a file and its owner, or a user and the group -it's in). Here's how you create a new type in Ruby: - - Puppet::Type.newtype(:mytype) do - ... - end - -Once created and placed in your Ruby search path, this type will become -immediately available in the language. - -You can create a type that overwrites existing types; this could be -considered a bug, but it allows Puppet to reload the files that define a -type. - -There are similar class methods for creating all of the different -attributes. Here is the simplified 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 - -See [Creating a Puppet Type](../programmers/creating-a-puppet-type.html) for more -information. - -*$Id$* diff --git a/documentation/documentation/about/notcfengine.page b/documentation/documentation/about/notcfengine.page deleted file mode 100644 index 3fd74110d..000000000 --- a/documentation/documentation/about/notcfengine.page +++ /dev/null @@ -1,214 +0,0 @@ ---- -inMenu: true -title: Puppet vs. Cfengine -orderInfo: 10 ---- - -[Cfengine](http://www.cfengine.org) is currently the most widely -deployed configuration management tool. In many ways, -[Puppet](/projects/puppet/) can be thought of as a next-generation -version of cfengine, in that many of puppet's design goals are -specifically derived from experience with cfengine and are meant to -overcome many of cfengine's weaknesses. However, Puppet was developed -based on experience with many tools, and it was heavily influenced by a -lot of time spent on theory, so there are some significant differences -between Puppet and cfengine. - -This document summarizes the primary advances that Puppet makes over -cfengine's current state. Left out of this document are any process decisions -that also led to Puppet's creation (e.g., the difficulty in getting -significant changes accepted to cfengine). - -# Extensibility - -One of the biggest differences between Cfengine and Puppet is how easy it is -to extend Puppet. There are many places in Puppet where you can create your -own classes and Puppet will load them automatically, making them available for -use immediately with no modification to the core. For instance, you can -create [new native resource types](../programmers/creating-a-puppet-type.html) -(that is, types written entirely in Ruby), drop them where Ruby can find them, -and just start using them -- Puppet will automatically load those types for -you. In addition to the types themselves, you can create -[new providers](../programmers/providers.html), to support new package -managers, for instance. There are a few other areas that will automatically -load your extensions, such as the report handlers. - -In contrast, Cfengine has a very limited interface for expansion -- you can -call out to modules using a shell interface. This limits the interface itself -to being very simple, but it also means you don't get good logging, noop -control, or much else. - -You could theoretically add new native types in C to Cfengine, but that would -require modification of the entire tree, from the lexer through the parser and -all the way through to the backend. - -# Abstraction - -Cfengine is a great way to scale common administrative practices -- you can -move from using SSH and a for loop to using Cfengine pretty smoothly. -However, there is just as much complexity present in either form. You still -have to handle file contents, and you still have to manage operating system -differences yourself -- you have to know whether it's ``useradd`` or -``adduser``, whether it's ``init`` or Sun's ``SMF``, and what the format of the -filesystem tab is. - -Puppet's primary goal is to provide enough abstraction so that you do not have -to know those details. You can speak in terms of users, services, or -filesystems, and Puppet will translate them to the appropriate commands on -each system. Puppet administrators are free to focus on the complexity of -their networks, rather than being forced to also handle that complexity plus -the complexity of the differences between the operating systems. - -Puppet's development was heavily influenced by the many external modules that -its author wrote for cfengine, each module managing a separate element like -users, packages, or cron jobs, and one of Puppet's primary goals was to be -able to make it easy to expand the number of element types it can manage. - -# Dedication - -Puppet is supported by an organization dedicated to creating -the best system automation software, and we expect to have a staff of at -least a few people dedicated to development, support, consulting, and custom -development. Constrast this with cfengine, which is supported by a professor -whose primary use for the software is in research into anomalies. - -Cfengine's author is only now starting to invest on community involvement in -its development; while its author has always accepted patches from the -community, he has been hesitant to provide standard project features like a -version repository and a bug database, and as a result cfengine's large user -base has not resulted in a large development community. - -Because Reductive Labs is a commercial enterprise dependent on customer -satisfaction for its survival, our customers will have a large say in how best -to develop Puppet, and we'll be doing everything we can to develop a strong -community just as dedicated to Puppet and server automation as we are. Our -goal is also to have multiple developers dedicated full time to Puppet -development, which should significantly accelerate feature development -compared to cfengine. - -# Language Power - -While the two languages are superficially similar, the puppet language already -supports two critical features that cfengine forces you to hack around. -Puppet supports building higher level objects out of a set of low-level -objects including the ability to parameterize, and has a built-in ability to -express relationships between objects. For instance, here is how you might -define a reusable component for creating virtual hosts for apache, as you -might deploy them on Debian: - -<pre><code> - define vhost(ip = "*:80", docroot = false, htmlsource, order = 500, ensure = "enabled") { - # Set the docroot, if necessary - $realdocroot = $docroot ? { - false => "/export/docroots/$name/htdocs", - default => $docroot - } - - # pull down the data to serve - file { $docroot: source => $htmlsource, recurse => true } - - # Create the vhost config file - file { "/etc/apache2/sites-available/$name": - content => " -<VirtualHost $ip> - ServerAdmin luke at madstop.com - DocumentRoot $realdocroot - ServerName $name - ErrorLog /var/log/apache2/$name/logs/error_log - CustomLog /var/log/apache2/$name/logs/access_log common -</VirtualHost> -", - notify => Service[apache] # restart apache if this changes - } - - case $ensure { - enabled: { - # Create the link - file { "/etc/apache2/sites-enabled/$order-$name": - ensure => "/etc/apache2/sites-available/$name", - notify => Service[apache] - } - } - default: { - # Make sure the link is missing - file { "/etc/apache2/sites-enabled/$order-$name": - ensure => absent, - notify => Service[apache] - } - } - } - } -</code></pre> - -Note that you could pull that virtual host configuration into an external -template if you wanted: - - # Create the vhost config file - file { "/etc/apache/sites-available/$name": - content => template("vhost.erb") - notify => service[apache] # restart apache if this changes - } - -Now that you have the definition, you can reuse it as many times as you want: - - vhost { "reductivelabs.com": - htmlsource => "/nfs/html/reductivelabs.com" - } - - vhost { "madstop.com": - htmlsource => "/nfs/html/madstop.com" - } - -Or you can make a bunch at once: - - vhost { - "reductivelabs.com": htmlsource => "/nfs/html/reductivelabs.com"; - "madstop.com": htmlsource => "/nfs/html/madstop.com"; - "kanies.com": - htmlsource => "/nfs/html/kanies.com", - ip => "192.168.0.3:80"; - "nosite.com": - ensure => disabled, - htmlsource => "/nfs/html/nosite.com" - } - -This simple level of abstraction already puts you far beyond what cfengine -can do. Any function-like abstraction in cfengine must be done with -templating tools like m4. - -The initial goal is to provide ample power to express the true -complexity of a network configuration, but just as importantly we want to -support code sharing. There has been essentially zero success in sharing -configurations within the cfengine community because of how difficult basic -abstraction is with cfengine, so one of my primary goals with the language was -to make abstraction, within a network or across one, downright easy. - -# Decoupling - -Puppet's parser knows how to interact with the list of available element -types, but it never knows anything about specific types. Thus, adding a new -type only requires creating the type, you will never have to modify the parser -or anything else in the stack. In contract, new types in cfengine require -modifications all the way through the stack, including the lexer. Puppet will -even automatically load any new types you create -- just drop them into your -search path and you can start using them (or, even better, drop them into the -[plugins directory](../reference/configref.html) and the client will automatically -retrieve and load them). - -Puppet also uses the industry-standard XMLRPC protocol for communication -between Puppet clients and servers, so the protocol is easy to study and -either end could be replaced by another service if desired. You can write -your own tools to interact with Puppet clients, if you want. - -# Development Methodology - -Reductive Labs is a big believer in enhancing developer productivity. Puppet -is being written in Ruby because it is a high-level language that is easy to -use yet provides significant productivity enhancements over low-level -languages like C. Reductive Labs also strongly believes that unreadable code -is bad code; if you can't easily follow a code path in Puppet, then you've -found a bug. Lastly, we assiduosly unit test our code. We're always looking -for more ways to test our code, and every bug we quash gets turned into a unit -test so we know we'll never release that bug again. - -*$Id$* diff --git a/documentation/documentation/advanced/cfengine_module.page b/documentation/documentation/advanced/cfengine_module.page deleted file mode 100644 index e8ef81777..000000000 --- a/documentation/documentation/advanced/cfengine_module.page +++ /dev/null @@ -1,147 +0,0 @@ ---- -inMenu: true -title: Cfengine Module -orderInfo: 10 ---- -# Cfengine Module - -For those who are still using Cfengine but would like either to take advantage -of Puppet's greater abstractive or modeling capabilities, we have created a -Cfengine module that can connect the two tools. - -## How to Use It - -This module works by taking the classes set in Cfengine and using them in -Puppet. Cfengine automatically sets quite a few classes for you, and you can -set any custom classes you want; you can reuse this class structure to -decide what to do within Puppet. - -Puppet treats classes somewhat differently from Cfengine; they look like -classes in most other languages, in that they are syntactical elements that -wrap other Puppet code, like so: - - class apache { - package { apache: ensure => installed } - service { apache: ensure => running } - } - -Puppet classes can be organized in any file structure; I usually put each -class in a separate file in a ``classes`` subdirectory and load the whole -directory at once: - - # site.pp - import "classes/*" - -## Setting Up Cfengine - -Currently, the module must be retrieved [from subversion](../installing/fromsvn.html) or -from the online -[source browser](https://reductivelabs.com/cgi-bin/puppet.cgi/browser/trunk/ext/module_puppet). - -It must be placed into Cfengine's module directory (which, I -believe, still defaults to ``/var/cfengine/modules``). If you have not used -modules in Cfengine before, you will have to set up Cfengine to pull this -extra directory down in your ``update.conf`` file, most likely. - -In addition, you'll want to pull all of your Puppet manifests down. This -doesn't necessarily need to be done in the ``update.conf`` file, but it'd -likely make your life easier if it were, since then you don't have to worry -about ordering. It's also probably a good idea to follow the same basic -structure that Puppet already uses, naming your topmost file ``site.pp``. The -location of the files is not terribly important, so we'll use -``/var/puppet/manifests`` in the examples. - -Once the module is set up, execute it: - - control: - actionsequence = ( - "module_puppet /var/puppet/manifests/site.pp" - ) - -It is up to you where this code is in your configuration, and you might need to -rename the module to ``module:puppet``; check the Cfengine documentation. - -By default, the module will just load classes set in cfengine, but you can add -``--no-nodes`` to have it load node configurations if desired (see the rest -of the Puppet documentation for more detail) and of course you can set classes -in Puppet based on the Cfengine classes.. - -## Setting Up Puppet - -Once Cfengine is configured properly, you need to add the appropriate -classes to Puppet. Cfengine will be passing Puppet a list of all enabled -classes, and Puppet will search for any defined classes named for any of those -defined classes. Only classes that are set in Cfengine and exist in Puppet -will be applied; classes that are only set in Cfengine or only defined in -Puppet will not throw errors, they will just be ignored. - -Let's say you're running this module on your mail server; you could set the -``mailserver`` class in Cfengine and then create a ``mailserver`` class in -Puppet: - - class mailserver { - file { "/etc/courier-imap": - source => "...", - recurse => true - } - package { courier-imap: ensure => installed } - service { courier-imap: - ensure => running, - subscribe => [file["/etc/courier-imap"], package[courier-imap]] - } - } - -If the ``mailserver`` class is set in Cfengine, the Puppet module will -automatically apply this class, which pulls down the configuration files, -installs the package, and starts the service for courier-imap. The -``subscribe`` parameter causes Puppet to restart the courier-imap service if -the configuration files or the package change (notice how much easier this -service restart is than it would be in Cfengine), and it also makes sure that -the configuration files are synchronized before the service is started -(ordering in Puppet is easily specified using the ``subscribe``, ``require``, -``notify``, and ``before`` parameters). - -## Where to Use Puppet - -Puppet was largely developed as a successor to Cfengine, based on years of -Cfengine consulting and development; as a result, it overcomes some -significant shortcomings in Cfengine, and it makes the most sense to use -Puppet in those places where Cfengine is weakest. Specifically, Puppet -provides [higher-level types](../reference/typedocs.html#user) than Cfengine, supports -high-level abstractions akin to functions, and makes it easy to define your -own [custom types](../programmers/creating-a-puppet-type.html). - -Generally, it's probably best to start out using Puppet to manage elements -that Cfengine cannot manage or is not good at managing, such as users, -groups, and packages (I know Cfengine can manage a couple of package types, -but Puppet supports more types more flexibly). Also, managing services and -their dependencies can get very convoluted in Cfengine but are specified -directly in Puppet so they're a bit easier to manage. - -If you already have your own custom Cfengine modules for managing other types, -it might also make sense to rewrite these as Puppet types since your custom -types are treated as first-class types within Puppet's language, rather then -being restricted to use Cfengine's shell-script module interface. - -If you are using a templating system with Cfengine or are generating your -Cfengine configurations somehow, you might be especially happy with this -Puppet module, since you can create reusable types with external templates. -For an example, see the [Puppet vs. Cfengine comparison](../about/notcfengine.html). - -## Transitioning - -It should be possible to use this module to slowly transition from a pure -Cfengine implementation to a pure Puppet implementation. The easiest code to -transition will be those types that both tools support, like files, or which -Puppet supports as a superset of Cfengine's support, such as services. The -hardest code to transition will be ``editfiles`` code, since Puppet does not -and probably never will provide an analogous feature. Instead, you will need -to use something like external templates or create custom Puppet types. - -The more code you transition to being within Puppet, however, the easier your -configuration should be to maintain and develop. If there is functionality in -Cfengine that you cannot find a way to replicate within Puppet, please join -the [user list](https://mail.madstop.com/mailman/listinfo/puppet-users) or -#puppet on irc.freenode.net and ask for help. - -*$Id$* diff --git a/documentation/documentation/advanced/index.page b/documentation/documentation/advanced/index.page deleted file mode 100644 index 830d147f2..000000000 --- a/documentation/documentation/advanced/index.page +++ /dev/null @@ -1,21 +0,0 @@ ---- -inMenu: false -directoryName: Advanced Functionality -title: Advanced Functionality -orderInfo: 5 -subtreeLevel: 6 ---- - -Advanced Functionality -===================== -* [Using Puppet with Cfengine](cfengine_module.html) -* [Storing Configs in LDAP](ldapnodes.html) -* [Managing Puppet with PuppetShow](puppetshow.html) -* [Transaction Reporting](reports.html) -* [Using Tags](tags.html) -* [Templating with ERB](templating.html) -* [Virtual Resources](virtual.html) - - - -*$Id$* diff --git a/documentation/documentation/advanced/ldapnodes.page b/documentation/documentation/advanced/ldapnodes.page deleted file mode 100644 index 1623f9c20..000000000 --- a/documentation/documentation/advanced/ldapnodes.page +++ /dev/null @@ -1,108 +0,0 @@ ---- -inMenu: true -title: Storing Configs in LDAP -orderInfo: 50 ---- -# Storing Configs in LDAP - -By default, ``puppetmasterd`` looks for nodes in its normal manifests, but you -can instead have it look in LDAP. This works especially well if you are -already storing your host/IP information in LDAP. - -I've only used [OpenLDAP](http://www.openldap.org/) to do this, but it should -work just as well with -[Fedora Directory Server](http://directory.fedora.redhat.com/wiki/Features) or -[Sun's Directory Server](http://www.sun.com/software/products/directory_srvr/home_directory.xml), -although you'll have to translate the schema to work with them. - -This guide will go through what it takes to modify an existing OpenLDAP setup; -please check -[their documentation](http://www.openldap.org/doc/admin/quickstart.html) -to get to that point. - -## Modifying your LDAP Schema - -You first have to provide the Puppet schema to your LDAP server. You can find -the Puppet schema -[in subversion](https://reductivelabs.com/cgi-bin/puppet.cgi/browser/trunk/ext/ldap/puppet.schema). -Stick this schema in your schema directory (I'm writing this guide on Debian, -so I'll be using their paths for examples; modify according to your site), -which will be something like ``/etc/ldap/schema``; I recommend keeping the -``puppet.schema`` name. - -With the schema file in place, modify your ``slapd.conf`` to load this schema; -just add it to the list of schema files loaded: - - include /etc/ldap/schema/core.schema - include /etc/ldap/schema/cosine.schema - include /etc/ldap/schema/nis.schema - include /etc/ldap/schema/inetorgperson.schema - include /etc/ldap/schema/puppet.schema - ... - -Restart your server, making sure it comes back up, and you're all set. - -## Loading Nodes Into LDAP - -In my opinion, the LDAP tool space is still depressingly spare. I generally -use my own [ldapsh](/projects/ldapsh/) tool to manage LDAP, but that does not -work well for data loading. However you decide to load the data, you need to -create host entries (usually ``device`` entries, probably with ``ipHost`` as -an auxiliary class) and then add the Puppet data. This is what my workstation -definition looks like in LDAP: - - dn: cn=culain,ou=Hosts,dc=madstop,dc=com - objectClass: device - objectClass: ipHost - objectClass: puppetClient - objectClass: top - objectClass: enHost - cn: culain - ipHostNumber: 192.168.0.3 - hardwareModel: i686 - puppetclass: webserver - puppetclass: puppetserver - puppetclass: mailserver - parentnode: basenode - -The DN I'm using for my host follows the model that I recommend for all LDAP -repositories. This will work well if you decide to start using LDAP as an -nsswitch source. It doesn't really matter to Puppet, though; it just does a -query against the search base you specify, it doesn't try to guess your DN. - -## Configuring Puppet to use LDAP - -Once you have your data in LDAP, you just need to configure Puppet to look -there. It's pretty much always ``puppetmasterd`` that will be looking in LDAP -(unless you're using ``puppet`` and setting ``--use-nodes``), so you need to -modify (or create) your ``puppetmasterd.conf`` file. There are only two -required settings: ``ldapnodes`` to indicate you want to look for nodes in -LDAP and ``ldapbase`` for where to search for LDAP nodes. You'll probably -also want to specify ``ldapserver``, since the default is ``ldap``, which -likely won't work for most people. This is what the relevant portion of my -``puppetmasterd.conf`` file looks like: - - [ldap] - ldapnodes = true - ldapserver = culain.madstop.com - ldapbase = dc=madstop,dc=com - -In other words, enable searching for nodes in LDAP by setting ``ldapnodes`` -to true, and then provide the information necessary to make it work. It's a -good idea to actually specify the Hosts tree as your search base (e.g., -``ldapbase = ou=Hosts,dc=madstop,dc=com``), but my database is small enough -that it doesn't matter. - -You'll need to restart the daemon (I'm working on automatically reloading -config files, but I'm not there yet), but then you should have LDAP node -lookup working. You'll be able to keep all of your node definitions in LDAP -and your class definitions in your manifests. - -## Default Nodes - -Note that Puppet also supports default node definitions, named (imaginatively) -``default``. You can use this to provide a minimal configuration for new -nodes until you get around to configuring each node. Without a default node -configuration, unconfigured nodes will fail. - -*$Id$ diff --git a/documentation/documentation/advanced/puppetshow.page b/documentation/documentation/advanced/puppetshow.page deleted file mode 100644 index 00a0ad8fb..000000000 --- a/documentation/documentation/advanced/puppetshow.page +++ /dev/null @@ -1,72 +0,0 @@ ---- -inMenu: true -title: Managing Puppet with PuppetShow -orderInfo: 50 ---- -# Managing Puppet with PuppetShow - -I have begun work on a simplistic web-based Puppet manager based on -[Rails](http://rubyonrails.org), called PuppetShow. It's in a very primitive -state -- including having no authentication, so use at your own risk -- but -it's a good proof of concept. - -To get it working, first check out the -[code](https://reductivelabs.com/svn/puppetshow). Then set up your apache -config to serve it. This is what mine looks like: - - <VirtualHost 192.168.0.101:80 192.168.0.102:80 192.168.0.3:80> - ServerAdmin luke@madstop.com - SetEnv RAILS_ENV development - ServerName puppet.madstop.com - ServerAlias puppet - DocumentRoot /var/lib/puppetshow/public - ErrorLog /var/lib/puppetshow/log/apache.log - - <Directory /var/lib/puppetshow/public/> - Options ExecCGI FollowSymLinks - AddHandler cgi-script .cgi - AllowOverride all - Order allow,deny - Allow from all - </Directory> - </VirtualHost> - -Now we just need to get the puppet internal stuff working. We could use -either ``rake`` or Puppet to do this, but for whatever reason I decided to use -Puppet. I've created a ``setup.pp`` file in the root of the tree, so you just -need to modify that as appropriate (in particular, I have a Facter lib that -sets ``$home`` for me, so you'll probably need to set that), then run: - - sudo puppet -v setup.pp - -At that point you should have a functional app. Like I said, there's no -navigation at all, so you need to know what's out there. The first thing you -need to do is start a daemon that this app can connect to. Pick your victim, -create a namespace auth file (defaults to -``/etc/puppet/namespaceauth.conf``): - - [fileserver] - allow *.madstop.com - - [puppetmaster] - allow *.madstop.com - - [pelementserver] - allow puppet.madstop.com - -Then start your client: - - puppetd -v --listen --no-client - -Here we're telling it to start the listening daemon but not to run the config. -You can obviously use whatever options you want, though. - -Now you should be able to just go to your app. At this point, you need to -know the name of the machine you want to connect to and the name of a type to -look at. Say you're connecting to culain (my workstation's name), and you -want to look at users; this would be your URL: -http://puppet.domain.com/remote/culain/user/list - -Replace as appropriate for your site. - -*$Id$* diff --git a/documentation/documentation/advanced/reports.page b/documentation/documentation/advanced/reports.page deleted file mode 100644 index bd1eb7901..000000000 --- a/documentation/documentation/advanced/reports.page +++ /dev/null @@ -1,106 +0,0 @@ ---- -inMenu: true -title: Transaction Reporting -orderInfo: 50 ---- -# Transaction Reporting - -Puppet can be configured to run specialized reports to help you to better keep track of your configurations. - -## Setting Up Reporting - -Enabling and configuring reports must be handled both on the client and server as the client doesn't include reporting information unless explicitly requested. - -### Turn on reporting on the client-side. - -In order to turn on reporting on the client-side (`puppetd`), the `report` argument must be given to the `puppetd` executable either by passing the argument to the executable on the command line, like this: - - $ puppetd --report - -or by including the configuration parameter in the `puppetd` configuration file, usually located in `/etc/puppet/puppetd.conf`. Take this `puppetd.conf` for instance, - - # - # /etc/puppetd.conf - # - [puppetd] - report = true - - -With this setting enabled, the client will then send the data necessary for reporting to the puppetmasterd server at the appropriate times. - -### Turn on reporting on the server-side - -Next, the server must be configured to intepret the report results. We'll tell it which reports to run by giving it a comma-separated list of reports we want to run against the client-submitted data. Again, we can do this from the command line, like so: - - $ puppetmasterd --reports tagmail,daily,security - -or you might enclose the list of reports in quotes: - - $ puppetmasterd --reports "tagmail,daily,security" - -note that leaving spaces in between the report names will result in an error: - - $ puppetmasterd --reports tagmail, daily, security # Wrong. - -or we can include these configuration parameters in the configuration file, typically `/etc/puppet/puppetmasterd.conf`. For example, - - # - # /etc/puppetmasterd.conf - # - [puppetmasterd] - reports = tagmail,daily,security - -Note that in the configuration file, the list of reports should be comma-separated without spaces and not enclosed in quotes (which is otherwise acceptable for a command-line invocation). - -You may also wish to specify the directory where reports will be stored with the [reportdirectory](../reference/configref.html#reportdirectory) parameter. Furthermore, transaction -reports can optionally be sent to a special report server (not necessarily the server or -client). This server can be specified with the [reportserver](../reference/configref.html#reportserver). - -For more about configuring your server, take a look at the section on [Configuration Reference](../reference/configref.html). - -## Available reports: - -### tagmail - -The `tagmail` report uses a "tagmap" mapping file to match certain reporting tags to certain e-mail recipients and sends messages with that tag to the appropriate recipients. The wildcard tag `all` matches all transactions. - -#### tagmap - -The mapping between reporting tags and email addresses, typically `/etc/puppet/tagmail.conf`. - - # - # /etc/puppet/tagmail.com - tagmail config - # - all: root@localhost - mail: postmaster@domain.com - sun: solarisadmins@domain.com - - -#### sendmail - -Where to find the sendmail binary with which to send email. - -#### reportfrom - -The 'from' email address for the reports. -Default: report@hostname.domain.you - -#### smtpserver - -The server through which to send email reports. - -### rrdgraph - -The `rrdgraph` report reports on the puppet system and its operations. The reports are stored as HTML in the rrd directory, so puppet must have write access to this directory. - -#### rrddir -The directory into which puppet will put the web-ready report files. Puppet will create one subdirectory for each host here and put host-specific data in each subdirectory. This directory will need to be puppet-writable. - -#### rrdgraph -Defines whether RRD information should be graphed (boolean). - -#### rrdinterval -How often RRD should expect data. This should match how often the hosts report back to the server. - - -* $Id$ diff --git a/documentation/documentation/advanced/tags.page b/documentation/documentation/advanced/tags.page deleted file mode 100644 index 46960f00d..000000000 --- a/documentation/documentation/advanced/tags.page +++ /dev/null @@ -1,81 +0,0 @@ ---- -inMenu: true -title: Using Tags -orderInfo: 50 ---- -# Using Tags - -Puppet allows for arbitrary tags to be applied to any or all objects in its configuration. You can use these tags to control your configuration roll-out with greater precision or greater complexity. - -## Invoking `puppet` in a Tag-Restricted Context - -One way to make use of tagging in `puppet` is to use tags at invocation-time to restrict which objects will be taken into consideration at run-time. In addition to the section below, you might want to glance at the [tags](../reference/configref.html#tags) section of the [Configuration Reference](../reference/configref.html). - -### Testing Configurations with Tags - -You can also specify tags on the command-line. This can be very useful for testing just a portion of the configuration, for instance, when you are first developing your site manifests. - - $ puppetd --tags solaris - -In the example above, we might want to only test the solaris hosts (perhaps because the HP-UX and Linux host configuration isn't stable yet). - -Specifying tags on the command-line might also be useful if your configuration cycle occurs in multiple phases, e.g.: - - $ puppetd --tags phase1,morning - -The invocation above might be used to execute only a select phase of the configuration process, here, using both procedural time ("phase1") as well as real chronological time ("morning"). - -### Specifying Tags in Configuration Files - -Tags can be used in configuration files to create a permanent context for the host's configuration. For instance, the host below is configured to configure itself only against objects tagged with "global", "westside", or "subnet7". Presumably, then, this network is categorized by physical geography ("westside") as well as by network topology ("subnet7"). - - # - # /etc/puppet/puppetd.conf - # - tags = global,westside,newnet - - - -## Specifying Tags for Different Configuration Scopes - -In order to make use of the tagging capability of Puppet, however, you must first set meaningful -tags in your object definitions. - -### Specifying Tags Explicitly in Object Definitions - -The easiest way to mark an object with a tag is to do it explicitly with the "tag" [metaparameter](../reference/typedocs.html#metaparameters). Since it is a metaparameter, it can be set on -any object. In the example below, we're tagging this file object, "/etc/httpd", with the tag -"apache", since it is part of the Apache webserver configuration. - - # - # /etc/puppet/manifests/site.pp - # - file { "/etc/httpd": - ensure => directory, - mode => 0755, - owner => $rootuser, - tag => apache - } - -### Automatic Tagging - -All language statements enclosed in a `node`, `define` or `class` structure (read more about puppet control structures [here](../language/structures.html)) will automatically be tagged with the name of that statement. These automatically-applied tags will be inherited by any object enclosed in that class, regardless of the depth of enclosure. - -Let's take a look at the configuration we looked at above, with a slight change: - - # - # /etc/puppet/manifests/site.pp - # - class apache { - file { "/etc/httpd": - ensure => directory, - mode => 0755, - owner => $rootuser, - tag => apache # This line is now redundant - } - } - -Now, since the file object `"/etc/httpd"` is automatically tagged with "apache" because it is contained in the class named "apache", it is no longer necessary to explicitly tag it with the -"tag" metaparam. - -* $Id$ diff --git a/documentation/documentation/advanced/templating.page b/documentation/documentation/advanced/templating.page deleted file mode 100644 index 82de96272..000000000 --- a/documentation/documentation/advanced/templating.page +++ /dev/null @@ -1,102 +0,0 @@ ---- -inMenu: true -title: Templating with ERB -orderInfo: 50 ---- -# Templating with ERB - -Puppet supports templating via -[ERB](http://www.ruby-doc.org/stdlib/libdoc/erb/rdoc/), which is part of the -Ruby standard library and is used for many other projects including Ruby on -Rails. Templates are evaluated via a simple function: - - $value = template("mytemplate.erb") - -You can specify the full path to your template, or you can put all your -templates in Puppet's ``templatedir``, which usually defaults to -``/var/puppet/templates`` (you can find out what it is on your system by -running ``puppet --configprint templatedir``). - -Templates are always evaluated by the parser, not by the client. This means -that if you are using ``puppetmasterd``, then the templates only need to be on -the server, and you never need to download them to the client. There's -no difference to the client between using a template and specifying -all of the text as a string. - -Templating is pretty simple: You can reference any variables within your -template that are defined within the enclosing scope. This is especially -useful for generating complete files; here is how I generate the Apache -configuration for my [Trac](http://trac.edgewall.org/) sites: - -<pre><code> - define tracsite($cgidir, $tracdir) { - file { "trac-$name": - path => "/etc/apache2/trac/$name.conf", - owner => root, - group => root, - mode => 644, - require => file[apacheconf], - content => template("tracsite.erb"), - notify => service[apache2] - } - - symlink { "tracsym-$name": - path => "$cgidir/$name.cgi", - ensure => "/usr/share/trac/cgi-bin/trac.cgi" - } - } -</code></pre> - -And then here's my template: - -<pre><code> - <Location "/cgi-bin/<%= name %>.cgi"> - SetEnv TRAC_ENV "/export/svn/trac/<%= name %>" - </Location> - - # You need something like this to authenticate users - <Location "/cgi-bin/<%= name %>.cgi/login"> - AuthType Basic - AuthName "Trac" - AuthUserFile /etc/apache2/auth/svn - Require valid-user - </Location> -</code></pre> - -You can see that I put each Trac configuration into a separate file, and then -I just tell Apache to load all of these files: - - Include /etc/apache2/trac/[^.#]* - -The above template is quite simple, in that it only uses the Puppet-defined -``name`` variable, but it provides a clean separation between the format of -the configuration file and how I generate it. - -## Iteration - -Puppet's templates also support iteration. If the variable you are accessing -is an array, you can iterate over it. Given Puppet code like this: - - $values = [val1, val2, otherval] - -You could have a template like this: - -<pre><code> - <% values.each do |val| %> Some stuff with <%= val %> <% end%> -</code></pre> - -This would produce: - - Some stuff with val1 - Some stuff with val2 - Some stuff with otherval - -Note that ERB template lines that just have code on them get translated into -blank lines, so if you were to split the above code into three lines, you -would get two blank lines between each line of output. - -Internally, Puppet's values get translated to real Ruby values, including -``true`` and ``false``, so you can be pretty confident that variables will -behave as you might expect. - -*$Id$* diff --git a/documentation/documentation/advanced/virtual.page b/documentation/documentation/advanced/virtual.page deleted file mode 100644 index c75a497da..000000000 --- a/documentation/documentation/advanced/virtual.page +++ /dev/null @@ -1,144 +0,0 @@ ---- -inMenu: true -title: Virtual Resources -orderInfo: 50 ---- - -## Virtual Resources - -By default, any resource you describe in a client's Puppet config will -get sent to the client and be managed by that client. However, as of -0.20.0, resources can be specified in a way that marks them as virtual, -meaning that they will not be sent to the client by default. You mark a -resource as virtual by prepending ``@`` to the resource specification; -for instance, the following code defines a virtual user: - - @user { luke: ensure => present } - -If you include this code (or something similar) in your configuration -then the user will never get sent to your clients without some extra -effort. - -## How This Is Useful - -Puppet enforces configuration normalization, meaning that a given -resource can only be specified in one part of your configuration. You -can't configure user ``johnny`` in both the ``solaris`` and ``freebsd`` -classes. - -For most cases, this is fine, because most resources are distinctly -related to a single Puppet class -- they belong in the ``webserver`` -class, ``mailserver`` class, or whatever. Some resources can not be -cleanly tied to a specific class, though; multiple otherwise-unrelated -classes might need a specific resource. For instance, if you have a -user who is both a database administrator and a Unix sysadmin, you want -the user installed on all machines that have either database -administrators or Unix administrators. - -You can't specify the user in the ``dba`` class nor in the ``sysadmin`` -class, because that would not get the user installed for all cases that -matter. - -In these cases, you can specify the user as a virtual resource, and -then mark the user as real in both classes. Thus, the user is still -specified in only one part of your configuration, but multiple parts of -your configuration verify that the user will be installed on the client. - -The important point here is that you can take a virtual resource and -mark it non-virtual as many times as you want in a configuration; it's -only the specification itself that must be normalized to one specific -part of your configuration. - -## How to Realize Resources - -There are two ways to mark a virtual resource so that it gets sent to -the client: You can use a special syntax called a ``collection``, or -you can use the simple function ``realize``. Collections provide a -simple syntax for marking virtual objects as real, such that they should -be sent to the client. Collections require the type of resource you are -collecting and zero or more attribute comparisons to specifically select -resources. For instance, to find our mythical user, we would use: - - User <| title == luke |> - -As promised, we've got the ``user`` type (capitalized, because we're -performing a type-level operation), and we're looking for the user whose -``title`` is ``luke``. "Title" is special here -- it is the value -before the colon when you specify the user. This is somewhat of an -inconsistency in Puppet, because this value is often referred to as the -``name``, but many types have a ``name`` parameter and they could have -both a title and a name. - -If no comparisons are specified, all virtual resources of that type will -be marked real. - -This attribute querying syntax is currently very simple. The only -comparisons available are equality and non-equality (using the ``==`` and -``!=`` operators, respectively), and you can join these comparisons -using ``or`` and ``and``. You can also parenthesize these statements, -as you might expect. So, a more complicated collection might look like: - - User <| (group == dba or group == sysadmin) or title == luke |> - -## Realizing Resources - -Puppet provides a simple form of syntactic sugar for marking -resource non-virtual by title, the ``realize`` function: - - realize User[luke] - realize(User[johnny], User[billy]) - -The function follows the same syntax as other function in the language, -except that only resource references are valid values. - -## Exported Resources - -Puppet provides an experimental superset of virtual resources, using a -similar syntax. In addition to these resources being virtual, they're -also ``exported`` to other hosts on your network. While virtual -resources can only be collected by the host that specified them, -exported resources can be collected by any host. You must set the -``storeconfigs`` configuration parameter to ``true`` to enable this -functionality, and Puppet will automatically create a database for -storing configurations (using [Ruby on Rails](http://rubyonrails.org)). - -This allows one host to configure another host; for instance, a host -could configure its services using Puppet, and then could export -Nagios configurations to monitor those services. - -There are two key syntactical differences between virtual and exported -resources. First, the special sigils are doubled for exported -resources, and second, only resource titles can be compared during a -collection of exported resources. - -Here is an example with exported resources: - - class ssh { - @@sshkey { $hostname: type => dsa, key => $sshdsakey } - Sshkey <<| |>> - } - -As promised, we use two ``@`` sigils here, and the angle brackets are -doubled inthe collection. - -The above code would have every host export its SSH public key, and then -collect every host's key and install it in the ``ssh_known_hosts`` file -(which is what the ``sshkey`` type does); this would include the host -doing the exporting. - -It's important to mention here that you will only get exported resources -from hosts whose configurations have been compiled. If hostB exports a -resource but hostB has never connected to the server, then no host will -get that exported resource. The act of compiling a given host's -configuration puts the resources into the database, and only resources -in the database are available for collection. - -### Exporting Is Still Experimental - -Unfortunately, this exporting is still experimental. We are in the -midst of revamping the database schema, in order to provide the same -level of functionality to exported objects as virtual objects have -(i.e., comparisons for any attribute). Until this is settled, this -functionality will be relatively fluid. - -*$Id$* diff --git a/documentation/documentation/reference/configref.header b/documentation/documentation/configref.header index 854eb1d99..854eb1d99 100644 --- a/documentation/documentation/reference/configref.header +++ b/documentation/documentation/configref.header diff --git a/documentation/documentation/reference/configref.page b/documentation/documentation/configref.page index c554f0bd3..c554f0bd3 100644 --- a/documentation/documentation/reference/configref.page +++ b/documentation/documentation/configref.page diff --git a/documentation/documentation/reference/functions.header b/documentation/documentation/functions.header index 9c58cd36a..9c58cd36a 100644 --- a/documentation/documentation/reference/functions.header +++ b/documentation/documentation/functions.header diff --git a/documentation/documentation/reference/functions.page b/documentation/documentation/functions.page index b926b75c3..b926b75c3 100644 --- a/documentation/documentation/reference/functions.page +++ b/documentation/documentation/functions.page diff --git a/documentation/documentation/index.page b/documentation/documentation/index.page index 736a7007b..21b054976 100644 --- a/documentation/documentation/index.page +++ b/documentation/documentation/index.page @@ -1,135 +1,18 @@ --- inMenu: false -directoryName: Documentation -title: Puppet Documentation -orderInfo: 1 -subtreeLevel: 5 +directoryName: Reference +title: Reference +orderInfo: 4 +subtreeLevel: 6 --- -How to Use This Guide -===================== -This guide is largely a pointer to smaller, more focused guides, although it -includes unique information when no appropriate smaller guide exists. - -Introduction to Puppet -======================= - -Puppet is a declarative *language* for expressing system configuration, a -*client and server* for distributing it, and a *library* for realizing the -configuration. - -The Puppet [Introduction](introduction.html) covers the basic architecture and -design goals, including whether and why you should be using Puppet on your -network. - -Cookbook -======== -This documentation collection is somewhat more of a reference than a how-to, -so we have developed a [Cookbook](/cookbook/) wiki for writing recipes and -how-tos for solving specific problems with Puppet. Because the cookbook is a -wiki, you can edit and create recipes yourself. - -Installation -=============== -There is an [Installation Guide](installation.html) meant for installation of -Puppet across a network. - -There is also a guide for [using Puppet from source](fromsvn.html), and one for -[testing Puppet](testing.html), to get an idea of what you can do without making a full -deployment. - -Command Line Executables -========================== - -This section will eventually have links to full man-pages for each executable, -but for now the man pages can be found by running the respective executable -with the '--help' flag (this requires the Rdoc::usage module, which is -often missing). - -However, most arguments for the executables are in the form of configuration -parameters used internally in the library. All of the executables are -written to accept any of these configuration parameters, and they -are all defined in the -[Puppet Executable Reference](configref.html). - -* **puppet** - - Stand alone Puppet Site Manifest Script evaluator. Parses, evaluates, - and implements a Site Manifest locally. - -* **puppetmasterd** - - Puppet Site Manifest Server Daemon. Runs on each host - serving/providing configurations to Puppet client hosts. - -* **puppetd** - - Puppet Client Host Configuration Daemon. Runs on each host whose - configuration is managed by Puppet. Requests a Host Specific Manifest - from a Puppet Manifest Server and implements it locally. - -* **puppetca** - - SSL Certificate Authority Server used for receiving cerification - requests from puppet clients. Puppet Client Hosts are required to have - their SSL certs signed by their Puppet Manifest Server's Authority - before they can be authenticated and authorized to recieve - configurations. - -* **puppetdoc** - - Command line tool for printing Puppet Default and Local Type Library - reference documentation. This is really only used internally. - -Type and Language Reference -============================== -The Puppet reference is split into two pieces: - -* [Language Tutorial](languagetutorial.html) - - A simple description of how the Puppet language functions, with multiple - examples. - +Reference +========= +* [Configuration Parameter Reference](configref.html) +* [Function Reference](functions.html) +* [Reports Reference](reports.html) * [Type Reference](typedocs.html) - A reference of all available Puppet Types. The types defined in this - reference represent the total ability of Puppet to manage your system -- if - an object is not in this reference, then Puppet cannot currently manage it. - -* [Language Reference](structures.html) - - A reference to all available language structures within Puppet. This - reference presents the limits of and options for expressibility within - Puppet. - -API Documentation -================= -Until I have time to write tutorials on how to extend Puppet, you might find -some benefit in perusing the [API docs](/downloads/puppet/apidocs/). -They're woefully incomplete as of the middle of 2006, but I'll be -updating them over time. - -Configuration -================ -Puppet configuration can be done through per-process configuration -files (e.g., ``puppetd.conf``) or on the command-line via switches. -Much of the documentation is available via ``--help`` switches on each -executable, but most of the useful switches are common to all -executables and are thus documented in the [executable reference](configref.html). - -There are some guides already, though: - -* [File Serving Configuration](fsconfigref.html) - -* [Puppet Certificates and Security](security.html) - -Additional Documentation -======================== -While the above links represent the standard, recommended documentation, there -is additional information available for those who are interested: - -* [Puppet Internals](howitworks.html) -* [How Cfengine compares to Puppet](notcfengine.html) *$Id$* diff --git a/documentation/documentation/installing/fromsvn.page b/documentation/documentation/installing/fromsvn.page deleted file mode 100644 index ac86e60a1..000000000 --- a/documentation/documentation/installing/fromsvn.page +++ /dev/null @@ -1,66 +0,0 @@ ---- -inMenu: true -title: Building from Source -orderInfo: 20 ---- -Puppet is currently implemented in Ruby and uses standard Ruby libraries. You -should be able to run Puppet on any Unix-style host with Ruby. Windows -support is planned but not currently available. - -## Before you Begin - -Make sure your host has Ruby version 1.8.2: - - $ ruby -v - -While Puppet should work with 1.8.1, there have been many reports of problems -with this version. - -Make sure you have Subversion: - - $ svn --version -q - -## Get the Source - -Puppet currently relies on another Reductive Labs tool, Facter. Create a working -directory and get them both: - - $ SETUP_DIR=~/svn - $ mkdir -p $SETUP_DIR - $ cd $SETUP_DIR - $ svn checkout https://reductivelabs.com/svn/facter/trunk facter - $ svn checkout https://reductivelabs.com/svn/puppet/trunk puppet - - -# Make it Available - -Last, we need to put the puppet binaries into our path and make the Puppet and -Facter libraries available to Ruby: - - $ PATH=$PATH:$SETUP_DIR/facter/bin:$SETUP_DIR/puppet/bin - $ RUBYLIB=$SETUP_DIR/facter/lib:$SETUP_DIR/puppet/lib - $ export PATH RUBYLIB - -Facter changes far less often than Puppet and it is very minimal (a single -library file and a single executable), so it is probably worth just installing -it: - - $ cd facter - $ sudo ruby ./install.rb - -## Test That It Works - -Now you can test that it is working. The best way to do that is described in -the [testing](testing.html) guide, and involves writing a short site manifest. Another -option is to run through all of the unit tests that ship with Puppet: - - $ cd $SETUP_DIR/puppet/test - $ rake - -This tends to take a long time, however, and is probably only useful if you -already know there's a problem and want to report a bug or if you are planning -on doing development. It is worth noting that some of these tests necessarily -modify your system, so unless you know what you are doing, **it is unadvisable -to run them as root**, and certainly not on a production system. - -*$Id$* diff --git a/documentation/documentation/installing/fsconfigref.page b/documentation/documentation/installing/fsconfigref.page deleted file mode 100644 index b9cedb111..000000000 --- a/documentation/documentation/installing/fsconfigref.page +++ /dev/null @@ -1,106 +0,0 @@ ---- -inMenu: true -title: Fileserver Configuration -orderInfo: 20 ---- - -# FileServer - -Puppet comes with both a client and server for copying files around. The file -serving function is provided as part of the central Puppet daemon, -``puppetmasterd``, and the client function is used through the ``source`` -attribute of ``file`` objects: - - # copy a remote file to /etc/sudoers - file { "/etc/sudoers": - mode => 440, - owner => root, - group => root, - source => "puppet://server/module/sudoers" - } - -As the example implies, Puppet's fileserving function abstracts local -filesystem topology by supporting fileservice "modules". You specify a path -to serve and a name for the path, and clients request it by name instead of by -path. This provides the ability to conceal from the client unnecessary -details like the local filesystem configuration. - -# File Format - -The default location for the file service is ``/etc/puppet/fileserver.conf``; -this can be changed using the ``--fsconfig`` flag to ``puppetmasterd``. -The format of the file is almost exactly like that of -[rsync](http://samba.anu.edu.au/rsync/), although it does -not yet support nearly the functionality of rsync. The configuration file -resembles INI-style files, but it is not exactly the same: - - [module] - path /path/to/files - allow *.domain.com - deny *.wireless.domain.com - -These three options represent the only options currently available in the -configuration file. The module name somewhat obviously goes in the brackets. -While the path is the only required option, the default security configuration -is to deny all access, so if no ``allow`` lines are specified, the module will -be configured but available to no one. - -The path can contain the patterns ``%h`` and ``%H``, which are dynamically -replaced by the client's short name and its fully qualified domain name, -both taken from the client's SSL certificate. This is useful in creating -modules where files for each client are kept completely separately, -e.g. for private ssh host keys. For example, with the configuration - - [private] - path /data/private/%h - allow * - -the request for file ``/private/file.txt`` from client -``client1.example.com`` will look for a file -``/data/private/client1/file.txt``, while the same request from -``client2.example.com`` will try to retrieve the file -``/data/private/client1/file.txt`` on the fileserver. - -# Security - -There are two aspects to securing the Puppet file server: Allowing specific -access, and denying specific access. By default no access is allowed. There -are three ways to specify a class of clients who are allowed or denied access: -By IP address, by name, or a global allow using ``*``. - -## Priority - -All ``deny`` statements are parsed before all ``allow`` statements, so if any -``deny`` statements match a host, then that host will be denied, and if no -``allow`` statements match a host, it will be denied. - -## Host Names - -Host names can be specified using either a complete hostname, or specifying an -entire domain using the ``*`` wildcard: - - [export] - path /export - allow host.domain1.com - allow *.domain2.com - deny badhost.domain2.com - -## IP Addresses - -IP address can be specified similarly to host names, using either complete IP -addresses or wildcarded addresses, but you can also use CIDR-style notation: - - [export] - path /export - allow 127.0.0.1 - allow 192.168.0.* - allow 192.168.1.0/24 - -## Global allow - -Specifying a single wildcard will let anyone into a module: - - [export] - path /export - allow * -*$Id$* diff --git a/documentation/documentation/installing/index.page b/documentation/documentation/installing/index.page deleted file mode 100644 index c23e24eed..000000000 --- a/documentation/documentation/installing/index.page +++ /dev/null @@ -1,19 +0,0 @@ ---- -inMenu: false -directoryName: Installing Puppet -title: Installing Puppet -orderInfo: 2 -subtreeLevel: 6 ---- - -Installing Puppet -================= -* [Test-Driving Puppet](testing.html) -* [Building from Source](fromsvn.html) -* [Installation](installation.html) -* [SSL Configuration](security.html) -* [Fileserver Reference](fsconfigref.html) - - - -*$Id$* diff --git a/documentation/documentation/installing/installation.page b/documentation/documentation/installing/installation.page deleted file mode 100644 index 6a3751a7f..000000000 --- a/documentation/documentation/installing/installation.page +++ /dev/null @@ -1,394 +0,0 @@ ---- -inMenu: true -title: Installation -orderInfo: 20 ---- -# Comments - -If there is anything about this introduction that is unclear or not correct, -please email luke at madstop.com about it or file a bug at -[the bug tracker](/cgi-bin/puppet.cgi). - -# Getting the Files - -You will need to install Puppet on all machines that will use it, including -both clients and servers. - -There are [packages][] available for some platforms, but for the rest -you will have to install using the [tarball][] or [GEMs][]. Install -instructions do not cover installing packages, since it is assumed you know -how to retrieve and install packages for your specific platform. - -## Prerequisites - -The only prerequisite for Puppet that doesn't come as part of the Ruby -standard library is [facter][], which is also developed by Reductive Labs. - -All other prerequisites for Puppet are Ruby libraries, and they should all -come with any standard Ruby 1.8.2 install. The other prerequisites, should -your OS not come with the complete standard library, are: - -* **base64** -* **cgi** -* **digest/md5** -* **etc** -* **fileutils** -* **ipaddr** -* **openssl** -* **strscan** -* **syslog** -* **uri** -* **webrick** -* **webrick/https** -* **xmlrpc** - -### Ruby - -I recommend using whatever Ruby comes with your system, since that's what I've -tested against in most cases and it's most likely to work correctly. If you -feel the particular need to build it manually, you can get the source from -[the Ruby site](http://ruby-lang.org/). - -#### Red Hat - -Puppet and Facter are now available in Fedora Extras, thanks to David -Lutterkort at Red Hat. Fedora users should be able to retrieve them via -yum from the Fedora Extras repository. Users of RHEL4 can get the package -from David's [yum repository](http://people.redhat.com/dlutter/yum/rhel4). -Please let the puppet-users mailing list know if you have built RPM's for -RHEL2.1 or RHEL3 (or the equivalent CentOS builds) - -If you are building ruby on Red Hat (at least on version 3), you -apparently must build it with ``CPPFLAGS=-I/usr/kerberos/include/``, else you -will have all kinds of unreasonable problems (thanks to Mario Martelli for -tracking that one down). - -#### Solaris - -There are Solaris packages for Puppet and Facter in the -[downloads](http://reductivelabs.com/downloads/packages/SunOS). These packages -suffice for both sparc and x86 (even though they're marked x86), but they -don't specify dependencies. They're automatically built during new releases, -so they should always be the latest. - -I have had mixed results with the Ruby packages from both -[Sunfreeware](http://sunfreeware.com) and [BlastWave](http://www.blastwave.org). -It might almost be easier to compile it manually for Solaris, but Ruby 1.8.4 -from BlastWave seems to be working right now. - -If you get segfaults, core dumps, or 'library missing ciphers' errors, that is -almost definitely a problem with that specific ruby package, not Puppet or -Ruby itself. - -#### Debian and Ubuntu - -Facter and Puppet now have quality -[Debian packges](http://packages.debian.org/unstable/admin/puppet), -thanks to Matthew Palmer and Jamie Wilkinson. You can download these packages -from any Debian mirror. - -The package maintainer for Ruby on these platforms has decided to split -the Ruby standard library into many packages. According to Eric Hollensbe, -this is the package dependency list for Puppet on Debian: - -* ruby -* irb -* ri -* rdoc -* libxmlrpc-ruby -* libopenssl-ruby -* libstrscan-ruby -* libsyslog-ruby -* libwebrick-ruby - -##### Note on Debian/Testing - -Note that **libruby1.8** versions above **1.8.4-1** on Debian/testing seem -to be broken, resulting in segfaults. Until an update gets released to fix -this, you should pin to library1.8, by putting something like the following -into ``/etc/apt/preferences``: - - Package: libruby1.8 - Pin: version 1.8.4-1 - Pin-Priority: 1001 - -If you have already upgraded your library1.8 package, you can downgrade it by -adding ``deb http://snapshot.debian.net/archive pool ruby1.8`` to your -``/etc/apt/sources.list`` and then running -``apt-get install libruby1.8=1.8.4-1``. - -#### SuSE - -Martin Vuk has set up the SuSE build service to create Puppet and Facter -packages, so you can get them -[there](http://software.opensuse.org/download/systemmanagement:/misc/). Older -versions of Puppet can still be retrieved from his old -[yum repository](http://lmmri.fri.uni-lj.si/suse/). - -#### Gentoo - -There are -[now](http://www.mail-archive.com/gentoo-server@lists.gentoo.org/msg02175.html) -ebuilds available for Puppet, created by Jos Gonzlez Gmez. - -Also, as of September 2006 there is a problem with the PPC Ruby package that -causes ``rdoc/usage`` to fail. The bug has been reported to the Gentoo folks. - -### Facter - -First install facter. Like Puppet, there are [packages][] available for -some platforms, but you might have to use the tarball: - - # get the latest tarball - wget http://reductivelabs.com/downloads/facter/facter-latest.tgz - - # untar and install it - gzip -d -c facter-latest.tgz | tar xf - - cd facter-* - sudo ruby install.rb # or become root and run install.rb - -There are also gems available in the [download][] directory. - -## Install Puppet - -Using the same mechanism, install the puppet libraries and executables: - - # get the latest tarball - wget http://reductivelabs.com/downloads/puppet/puppet-latest.tgz - - # untar and install it - gzip -d -c puppet-latest.tgz | tar xf - - cd puppet-* - sudo ruby install.rb # or become root and run install.rb - -## Alternative: Using RubyGems - -You can also use Reductive Labs' Gems server to install Facter and Puppet: - - gem install --remote --source http://reductivelabs.com/downloads facter - gem install --remote --source http://reductivelabs.com/downloads puppet - -For more information on RubyGems, see the [Gems User Guide][]. - -## Alternative alternative: Native Packages - -It is our goal to provide as many native packages as possible, but it's been -slow going. Until I have official native packages, David Lutterkort used spec -and init files from Duane Griffin to create native RPMs that should work on -Red Hat Enterprise 4 and Fedora Core 4. You can get them from his -[yum repository][]. - -There are also [Debian packages][], although they are not quite as well -maintained as the RPMs. - -# Building the Server - -Puppet is designed so that essentially all of its configuration can be -maintained on the server. The clients do not need copies of the configuration -manifests, nor any templates you might create, and Puppet knows how to -download any custom types or facts you create. Thus, the manifest you create -should just be on the server, and it will be compiled by the server for each -client. - -## Create Your Site Manifest - -Because the Puppet language is declarative, it does not make as much sense to -speak of "executing" Puppet programs, or to describe them as "scripts". We -choose to use the word *manifest* to describe Puppet programs, and we speak of -*applying* those manifests to the local system. Thus, a *manifest* is a text -document written in the Puppet language and meant to result in a desired -configuration. - -Puppet is written with the assumption that you will have one central manifest -capable of configuring your entire network, which we call the *site manifest*. -You could have multiple, separate site manifests if you wanted, but at this -point each of them would need their own servers. - -For more information on how to create the site manifest, see the -[Language Reference][] and the [Library Reference][]. - -Puppet will look for your site manifest in ``/etc/puppet/manifests/site.pp``, -so create ``/etc/puppet/manifests`` and add your manifest, along with any -files it includes, to that directory. It is highly recommended that you use -some kind of [version control][] on your manifests. - -### Example Manifests - -The site manifest can be as simple or as complicated as you want. A good -starting point is to make sure that your sudoers file has the appropriate -permissions: - - # site.pp - file { "/etc/sudoers": - owner => root, group => root, mode => 440 - } - -If you want to get more complicated, it's a good idea to split your -manifest into multiple files. For instance, you could split it based on -operating systems (e.g., Solaris and Red Hat) and server classes (e.g., -'webserver' and 'logserver'). I also find it useful to have a set of -functions, in an external file included first: - - # site.pp - - # import the functions - import "functions.pp" - - # import all of the os classes, like redhat.pp and solaris.pp - import "os/*" - - # import all of the server classes, like webserver.pp - import "classes/*" - -Here's an example of a generically useful function I use; it encapsulates the -source of files that I copy from a central server, and just saves a little -typing: - - # functions.pp - - define remotefile(owner = root, server = puppet, group = root, mode, source, backup = false, recurse = false) { - file { - $name: - mode => $mode, - owner => $owner, - group => $group, - backup => $backup, - source => "puppet://$server/dist/$source" - } - } - -You would use the function like this: - - remotefile { "/etc/sudoers": - mode => 440, source => "apps/sudo/sudoers" - } - -## Start the Central Daemon - -Most sites should only need a single central server. Reductive Labs will -soon publish a document describing how to build puppet architectures with -failover capabilities and achitectures that are capable of handling large -loads, but for now only a single server is supported. - -Decide which machine you want to be your central server; this is where you -will be starting ``puppetmasterd``. - -The best way to start any daemon is using your local server's service -management system, often in the form of ``init`` scripts. Eventually Puppet -will ship with an appropriate script for each platform (it already has -appropriate scripts for Red Hat, Debian, and Solaris), but in the meantime you -can either create your own, using an existing script as an example, or simply -run without one (not recommended for production environments). - -Other than the system manifest at ``/etc/puppet/manifests/site.pp``, -the last thing you'll need is to create the puppet user and group that the -daemon runs as. You can create these manually, or you can just start the -daemon with the ``--mkusers`` flag, and it should create both of them for you -(of course, this flag is only necessary the first time the daemon is run): - - /usr/bin/puppetmasterd --mkusers - -Even without the ``mkusers`` flag, it will automatically create all necessary -certificates, directories, and files. If you want the daemon to also function -as a file server, so your clients can copy files from it, you will need to -create a [fileserver configuration file][]; the daemon checks for the -existence of this file at startup and automatically enables or disables file -serving functionality. - -If you are still only testing, and do not have node definitions in your -site manifest (such as with the above example manifest) , tell -``puppetmasterd`` not to look for them: - - /usr/bin/puppetmasterd --nonodes - -Otherwise, you will need to define each of your nodes in your site manifest: - - node culain { - include workstation - } - -Alternatively, you can tell ``puppetmasterd`` to use -[LDAP for node storage](../advanced/ldapnodes.html). - -# Client Setup - -In most environments, the clients will need no initial configuration. They -will try to contact a server named ``puppet`` by default, so if you set up a -DNS alias pointing that to your Puppet server, your clients shouldn't need any -configuration. - -# Verifying Installation - -To verify that your daemon is working as expected, pick a single client to use -as a testbed. Once Puppet is installed on that machine, run a single client -against the central server to verify that everything is working appropriately. -You should start the first client in verbose mode, with the ``--waitforcert`` -flag enabled: - - puppetd --server myserver.domain.com --waitforcert 60 --test - -The default server for ``puppetd`` is ``puppet``, so you could just create a -CNAME of that to whatever server is running ``puppetmasterd``. - -Adding the ``--test`` flag here is equivalent to -adding ``--verbose --onetime --no-usecacheonfailure``. -This causes ``puppetd`` to stay in the foreground, -print extra output, only run once and then exit, and to just exit if the -remote configuration fails to compile (by default, ``puppetd`` will use a -cached configuration if there is a problem with the remote manifests). - -In running the client, you should see a message that the client did not -receive a certificate (this message will repeat every 60 seconds with the -above command). This is normal, since your server is not autosigning -certificates as a security precaution. On your server, list the waiting -certificates: - - puppetca --list - -You should see the name of the test client. Now go ahead and sign the -certificate: - - puppetca --sign mytestclient.domain.com - -Within 60 seconds, your test client should receive its certificate from the -server, receive its configuration, apply it locally, and exit normally. - -By default, ``puppetd`` runs with a ``waitforcert`` of five minutes; set the -value to 0 to disable it entirely. - -# Finishing Installation - -There are already init scripts available for some platforms (notably, Red Hat -versions, thanks to David Lutterkort's work on the [RPMs][]), but for -not-yet-supported platforms, you will need to create an init script that can -start and stop ``puppetd``. The process creates a PID file in its run -directory (``/var/puppet/run``, by default), so you can use that to stop it. - -The process will log to syslog by default in the daemon facility. - -Beta Notes -========== -There are some important notes to keep in mind about using the current versions of -Puppet: - -* Files are currently automatically reread when they are changed, within a - timeout of 60 seconds. -* Patches are welcome and encouraged. - -[developed]: /projects/facter/ -[download]: /downloads/ -[version control]: http://svnbook.red-bean.com/ -[fileserver configuration file]: fsconfigref -[Gems User Guide]: http://docs.rubygems.org/read/book/1 -[Language Reference]: structures.html -[Library Reference]: typedocs.html - -[packages]: /downloads/packages/ -[tarball]: /downloads/puppet/ -[gems]: /downloads/gems/ -[rpms]: /downloads/rpm/ - -[yum repository]: http://people.redhat.com/~dlutter/yum/ -[debian packages]: /downloads/packages/Debian/ - -*$Id$* diff --git a/documentation/documentation/installing/security.page b/documentation/documentation/installing/security.page deleted file mode 100644 index 9f94cc5f4..000000000 --- a/documentation/documentation/installing/security.page +++ /dev/null @@ -1,99 +0,0 @@ ---- -inMenu: true -title: SSL Configuration -orderInfo: 20 ---- -# Overview - -Puppet relies on standards wherever possible. In the case of security, it uses -standard SSL certificates for client and server verification. Because of the -cost of buying signed certificates for every client and the complexity of -managing your own certificate authority (CA), Puppet includes its own CA. -This CA has been optimized for use with Puppet but could also be used to -generate certificates for other purposes. The primary goal in certificate -management within Puppet has been to keep it simple, and wherever possible to -not make it even noticeable. - -# Certificates - - -## Authentication - -Certificates are the only method of authentication -- if a client's -certificate can be verified using standard SSL verification mechanisms, then -it is considered authenticated. - -## Client Certificate Generation - -The Puppet server, ``puppetmasterd``, is normally also the CA. Clients who -do not yet have signed certificates will automatically generate a key pair and -a certificate request, and then will connect to the server and provide it -with the certificate request. If the server has ``autosign`` turned on (which -is not necessarily recommended), then the autosign configuration file (which -defaults to ``/etc/puppet/autosign.conf``) is checked for whether the client's -name matches any contents. For instance, take the following configuration -file: - - hostname.domain.com - *.secure.domain.com - -This configuration would autosign certificate requests for -``hostname.domain.com`` and any hosts coming from ``*.secure.domain.com``. - -This configuration file is read each time a signature is asked for, so changes -to it can be short-lived and will be immediately noticed. - -# Server-Side Certificate Management - -In the normal case, certificate auto-signing will be disabled. In these -cases, certificates will have to be signed using the ``puppetca`` utility. -Prior to the 1.0 release it is expected that there will be email notification -of certificate requests waiting to be signed, but for now either the logs -must be watched or ``puppetca --list`` can be used list waiting requests. - -Once a request arrives, ``puppetca --sign <hostname>`` can be used to sign -the request. Adding the ``--all`` flag will sign all outstanding -requests. A list of all certificates ever issued by Puppet's CA can be -found in the file ``$cadir/inventory.txt``. - -All certificate files for a given host can be removed (for rebuilding hosts, -for instance) with ``puppetca --clean <hostname>``. - -Certificates, once issued, can be revoked with ``puppetca --revoke -<hostname|serial>``. The server consults the certificate revocation list -(CRL) every time a client tries to connect to the server; for revocations -to take effect, the server must be restarted after the certificate -revocation with ``puppetca``. - -# Access and Authorization - -Puppet currently has few network functions, so security has so far been -treated by them individually. It is expected that there will be some -system-wide security hooks prior to the 1.0 release, but the certificate -authentication already provides significant security. - -Recommendations on approaches are heartily recommended. - -# Examples - -To introduce a client machine to the puppet server, first run puppetd on -the client with the `waitforcert` parameter: - - $ puppetd --waitforcert 30 --server puppetserver.domain.net -v - -The client will request a certificate from the certificate authority -facility on the server called `puppetserver.domain.net`. - -Assuming that the machine `puppetserver` is not set to autosign any new -certificate requests (this is the default), you'll need to list the certificate -requests from the command line on the server with an invocation like this: - - $ puppetca --list - -You'll then be able to pick out the request by name (quite possibly, it will be the -only request waiting) and instruct the certificate authority to sign the request: - - $ puppetca --sign puppetclient-37.domain.net - - -*$Id$* diff --git a/documentation/documentation/installing/testing.page b/documentation/documentation/installing/testing.page deleted file mode 100644 index 1e29e9953..000000000 --- a/documentation/documentation/installing/testing.page +++ /dev/null @@ -1,90 +0,0 @@ ---- -inMenu: true -title: Test-driving Puppet -orderInfo: 20 ---- - -If you want to just test-drive Puppet, making the least commitment possible, -you can run it directly from the checked-out [source][], against a configuration -in a temporary directory. - -The default Puppet configuration directory (where it looks for its manifests, -and where it stores certificates and logs) is ``/etc/puppet`` if you are -running the executables as root or ``~/.puppet`` otherwise. All of the -executables accept a ``--confdir <directory>`` flag to change this directory. - -I often use my local Subversion sandbox for testing (i.e., I have my Puppet -configuration stored in Subversion and checked out in my home directory, and I -just test Puppet directly against this configuration). Normally Puppet would -make the configuration directory for you, but the server needs the ``site.pp`` -to exist, so you need to create the ``manifests`` subdirectory: - - $ mkdir -p /var/tmp/puppet/manifests - $ vi /var/tmp/puppet/manifests/site.pp - <create file> - -Alternatively, you can just specify the manifest itself: - - $ sudo puppetmasterd --verbose --manifest ~/svn/puppet/manifests/site.pp - -I also always at least run the daemons in verbose mode while testing. First -start the central daemon: - - $ sudo puppetmasterd --verbose --confdir /var/tmp/puppet - -By default, ``puppetmasterd`` looks for node definitions along these lines: - - node mymachine { - include $operatingsystem - } - -You can put any valid Puppet code in the structure, but the important -point is that the node definitions need to be there or you need to tell -``puppetmasterd`` they are not there by using the ``--nonodes`` argument. If -you are trying to write a config that works for both ``puppet`` (the -stand-alone executable) and ``puppetd`` (the client to ``puppetmasterd``), -then you should create the config without nodes and use the ``--nonodes`` -argument. - -Once you have the manifest, start the client, pointing it at the local server, -running in noop mode the first time: - - $ sudo puppetd --verbose --confdir /var/tmp/puppet --server localhost --noop --onetime - -This will connect to the server, retrieve the current machine's configuration, -and run it. In noop mode, this should work for any user, but if you run it as -a normal user you might get some errors if you are not in noop mode (e.g., -normal users cannot use 'chown'). - -Note that your ``site.pp`` file should have a [node][] definition for the host -connecting; otherwise you will get an error complaining of no configuration for -that host. It is possible to skip this requirement -- see the ``--help`` -output of ``puppetmasterd`` for details. - -Configuration Testing ---------------------- -Once you're successfully running the daemons, there are other useful flags you -can use to make your life easier. First is the '--test' flag for ``puppetd``, -which is the equivalent of running with ``--onetime --verbose --no-usecacheonfailure``, -which means the puppet client -will exit after the first run and will not use the cached configuration if the -central one is broken somehow (this is useful for those cases where you -accidentally cause a parsing error in the config). - -Also, you can narrow down what portion of the configuration you are testing by -using '--tag'. For instance, say you are running this on a machine that is an -ldapserver, namedserver, and webserver, and you're adding ntpserver to the -list of classes being evaluated. Rather than sitting through the entire -config every run, just apply the ntpserver elements: - - $ sudo puppet --server localhost --test --tag ntpserver - -Every element in Puppet is tagged with the class or definition enclosing that -element, all the way up to the base of the configuration, and it is also -tagged with the host name. So if 'classA' includes 'classB' which creates -'fileC', then 'fileC' will be tagged with both classes. - -[node]: structures.html#nodes -[source]: fromsvn.html - -*$Id$* diff --git a/documentation/documentation/internals/big-picture.page b/documentation/documentation/internals/big-picture.page deleted file mode 100644 index 06f1ade1d..000000000 --- a/documentation/documentation/internals/big-picture.page +++ /dev/null @@ -1,177 +0,0 @@ ---- -inMenu: true -title: The Big Picture -orderInfo: 60 ---- -# Big Picture - -Puppet is a **declarative language** for expressing system configuration, a -**client and server** for distributing it, and a **library** for realizing the -configuration. - -Rather than approaching server management by automating current techniques, -Puppet reframes the problem by providing a language to express the -relationships between servers, the services they provide, and the primitive -objects that compose those services. Rather than handling the detail of how -to achieve a certain configuration or provide a given service, Puppet users -can simply express their desired configuration using the abstractions they're -used to handling, like ``service`` and ``node``, and Puppet is responsible for -either achieving the configuration or providing the user enough information to -fix any encountered problems. - -This document is a supplement to the [Introduction](../about/introduction.html) and it is assumed that -readers are familiar with the contents of that document. - -# Less Detail, More Information - -A correct configuration must obviously provide the appropriate details, but a -configuration tool should understand that the details are generally the easy -part. The hard part of system configuration is understanding the -complex relationships between services and the objects that comprise those -services. One of the primary goals of Puppet is to allow users to push the -details into lower levels of the configuration and pull the relationships into -the foreground. - -For instance, take a typical Apache web server deployment. Puppet allows one -to encapsulate all of the primitives necessary for successful deployment into -one reusable object, and that object can even be abstracted to support -multiple apache versions. Here's how a simple apache definition might look -for a Debian server (Debian uses ``apache`` for 1.x versions and ``apache2`` -for 2.x versions): - - define apache(version, conf, user, group) { - # abstract across apache1 and apache2 - $name = $version ? { - 1 => "apache", - 2 => "apache2" - } - package{ $name: - install => true - } - - file { $conf: - user => $user, - group => $group, - source => $conf - } - - # we want the service to restart if the config file changes - # or if the package gets upgraded - service { $name: - running => true, - requires => [file[$conf], package[$name]] - } - } - -Now, with this configuration, one can easily set multiple servers up to run -different versions of apache. The key benefit here is that the information -necessary to run apache correctly is separated from the decision to do so on a -given host. For example: - - # import our apache definition file - import "apache" - - node server1 { - # use a locally-available config file - apache { apache-server1: - version => 1, - conf => "/nfs/configs/apache/server1.conf", - user => www-data, - group => www-data - } - } - - node server2 { - # use a config that we pull from elsewhere - apache { apache-server2: - version => 2, - conf => "http://configserver/configs/server2/httpd.conf" - user => www-data, - group => www-data - } - } - -Notice that our node configuration only specifies 1) that a given server is -running Apache, and 2) the information necessary to differentiate this -instance of apache from another instance. If a given detail is going to be -the same for all apache instances (such as the fact that the service should be -running and that it should be restarted if the configuration file changes), -then that detail does not have to be specified every time an Apache instance -is configured. - -# Describing Configuration - -Puppet's declarative language separates the "what" of the configuration from -the "how". The "how" is pushed into the library, which generally provides the -ability to manage a given entity on multiple platforms, isolating the Puppet -user from platform details. - -### Language Example: Class Hierarchy Using Inherit - -Inheritance can be used to override default values defined in base classes: - - class base { - file { "/etc/sudoers": - owner => root, - group => root, - mode => 440 - } - } - - # FreeBSD has a "wheel" group instead of a "root" group - class freebsd inherits base { - file { "/etc/sudoers": - group => wheel, - } - - } - -# Distributing Configuration - -The Puppet framework Library consists of a client and server. - -(picture/diagram: client, server, site-config -> host-config) - -A Puppet server is aware of the full configuration. As some component's -configuration aspects depend on the configuration of other components (e.g. the -firewall config includes the ports used by webservers), generating -configuration for a component requires being aware of full configuration. - -A Puppet client that runs on a specific host (or perhaps the same host as its -Puppet Server) is generally only concerned with the components to be configured -on that host. - -Puppet Clients normally request or "pull" configuration from their server. The -Server processes the configuration request for the host using a pre-generated -tree model of the classes and definitions from the site-config. - -When configuration needs to be "pushed" to the clients, the Server can be asked -to attempt to trigger each client to request "pull" a new host configuration. - -Example: Puppet server, library - -You can read more about the Puppet language in the Introduction_. (Add link to -user manual, when it's written) - - -# Realizing the Configuration - -The Puppet Client Library contains the component knowledge of how to reach -desired states and configurations for several objects: File, Package, etc. - -Example: Puppet Client, library: - - ...todo: file: transfer, mode, ownership... - -You can read more about the Puppet language in the Introduction_. -(Add link to user manual, when it's written) - -Some components such as the webserver and firewall, from the simple-website -example, require additional code to reach "closure". "Closure" is when the -component is entirely responsible for implementing its own configuration. - -Much as database applications abstract the mechanics of storing, indexing, and -searching their data, a component ideally should abstract the specifics of how -to store, confirm, and implement its requested configuration. - -*$Id$* diff --git a/documentation/documentation/internals/howitworks.page b/documentation/documentation/internals/howitworks.page deleted file mode 100644 index 3a101745c..000000000 --- a/documentation/documentation/internals/howitworks.page +++ /dev/null @@ -1,285 +0,0 @@ ---- -inMenu: true -title: How It Works -orderInfo: 60 ---- -# How it Works: Introduction - -The goal of this document is to describe how a manifest you write in Puppet -gets converted to work being done on the system. This process is relatively -complex, but you seldom need to know many of the details; this document only -exists for those who are pushing the boundaries of what Puppet can do or who -don't understand why they are seeing a particular error. It can also help -those who are hoping to extend Puppet beyond its current abilities. - -# High Level - -When looked at coarsely, Puppet has three main phases of execution -- -compiling, instantiation, and configuration. - -## Compiling - -Here is where we convert from a text-based manifest into the actual code we'll -be executing. Any code not meant for the host in question is ignored, and any -code that is meant for that host is fully interpolated, meaning that variables -are expanded and all of the results are literal strings. - -The only connection between the compiling phase and the library of Puppet -elements is that all resulting elements are verified that the referenced type -is valid and that all specified attributes are valid for that type. There is -no value validation at this point. - -In a networked setup, this phase happens entirely on the server. The output -of this phase is a collection of very simplistic elements that closely -resemble basic hashes and arrays. - -## Instantiation - -This phase converts the simple hashes and arrays into Puppet library objects. -Because this phase requires so much information about the client in order to -work correctly (e.g., what type of packaging is used, what type of services, -etc.), this phase happens entirely on the client. - -The conversion from the simpler format into literal Puppet objects allows -those objects to do greater validation on the inputs, and this is where most -of the input validation takes place. If you specified a valid attribute but -an invalid value, this is where you will find it out, meaning that you will -find it out when the config is instantiated on the client, not (unfortunately) -on the server. - -The output of this phase is the machine's entire configuration in memory and -in a form capable of modifying the local system. - -## Configuration - -This is where the Puppet library elements actually modify the system. Each of -them compares their specified state to the state on the machine and make any -modifications that are necessary. If the machine exactly matches the -specified configuration, then no work is done. - -The output of this phase is a correctly configured machine, in one pass. - -# Lower Level - -These three high level phases can each be broken down into more steps. - -## Compile Phase 1: Parsing - -* *Inputs* Manifests written in the Puppet language -* *Outputs* Parse trees (instances of [AST][ast] objects) -* *Entry* [Puppet::Parser::Parser#parse][parse] - -At this point, all Puppet manifests start out as text documents, and it's the -parser's job to understand those documents. The parser (defined in -``parser/grammar.ra`` and ``parser/lexer.rb``) does very little work -- it -converts from text to a format that maps directly back to the text, building -parse trees that are essentially equivalent to the text itself. The only -validation that takes place here is syntactic. - -This phase takes place immediately for all uses of Puppet. Whether you are -using nodes or no nodes, whether you are using the standalone puppet -interpreter or the client/server system, parsing happens as soon as Puppet -starts. - -## Compile Phase 2: Interpreting - -* *Inputs* Parse trees (instances of [AST][] objects) and client information - (collection of facts output by [Facter][]) -* *Outputs* Trees of [TransObject][] and [TransBucket][] instances (from - transportable.rb) -* *Entry* [Puppet::Parser::AST#evaluate][ast_evaluate] -* *Exit* [Puppet::Parser::Scope#to_trans][] - -Most configurations will rely on client information to make decisions. When -the Puppet client starts, it loads the [Facter][] library, collects all of the -facts that it can, and passes those facts to the interpreter. When you use -Puppet over a network, these facts are passed over the network to the server -and the server uses them to compile the client's configuration. - -This step of passing information to the server enables the server to make -decisions about the client based on things like operating system and hardware -architecture, and it also enables the server to insert information about the -client into the configuration, information like IP address and MAC address. - -The [interpreter][] combines the parse trees and the client information into a -tree of simple [transportable][] objects which maps roughly to the configuration -as defined in the manifests -- it is still a tree, but it is a tree of classes -and the elements contained in those classes. - -### Nodes vs. No Nodes - -When you use Puppet, you have the option of using [node elements][] or not. If -you do not use node elements, then the entire configuration is interpreted -every time a client connects, from the top of the parse tree down. In this -case, you must have some kind of explicit selection mechanism for specifying -which code goes with which node. - -If you do use nodes, though, the interpreter precompiles everything except the -node-specific code. When a node connects, the interpreter looks for the code -associated with that node name (retrieved from the Facter facts) and compiles -just that bit on demand. - -## Configuration Transport - -* *Inputs* [Transportable][] objects -* *Outputs* [Transportable][] objects -* *Entry* [Puppet::Server::Master#getconfig][] -* *Exit* [Puppet::Client::MasterClient#getconfig][] - -If you are using the stand-alone puppet executable, there is no configuration -transport because the client and server are in the same process. If you are -using the networked puppetd client and puppetmasterd server, though, the -configuration must be sent to the client once it is entirely compiled. - -Puppet currently converts the Transportable objects to [YAML][], which it then -CGI-escapes and sends over the wire using XMLRPC over HTTPS. The client -receives the configuration, unescapes it, caches it to disk in case the server -is not available on the next run, and then uses YAML to convert it back to -normal Ruby Transportable objects. - -## Instantiation Phase - -* *Inputs* [Transportable][] objects -* *Outputs* [Puppet::Type][] instances -* *Entry* [Puppet::Client::MasterClient#getconfig][] -* *Exit* [Puppet::Type#finalize][] - -To create Puppet library objects (all of which are instances of [Puppet::Type][] -subclasses), ``to_trans`` is called on the top-level transportable object. -All container objects get converted to [Puppet::Type::Component][] instances, -and all normal objects get converted into the appropriate Puppet type -instance. - -This is where all input validation takes place and often where values get -converted into more usable forms. For instance, filesystems always return -user IDs, not user names, so Puppet objects convert them appropriately. -(Incidentally, sometimes Puppet is creating the user that it's chowning a file -to, so whenever possible it ignores validation errors until the last minute.) - -The last stage of the instantiation process finalizes the object dependencies. -One of the goals of the Puppet language is to make file order matter as little -as possible; this means that a Puppet object needs to be able to require other -objects listed later in the manifest, which means that the required object will -be instantiated after the requiring object. So, this finalization stage is used -to actually handle all of these requirements -- Puppet objects use their -references to objects and verify that the objects actually exist. - -## Configuration Phase 1: Comparison - -* *Inputs* [Puppet::Type][] instances -* *Outputs* [Puppet::StateChange][] objects collected in a [Puppet::Transaction][] - instance -* *Entry* [Puppet::Client::MasterClient#apply][] -* *Exit* [Puppet::Type::Component#evaluate][component_evaluate] - -Before Puppet does any work at all, it compares its entire configuration to -the state on disk (or in memory, or whatever). To do this, it recursively -iterates across the tree of [Puppet::Type][] instances (which, again, still -roughly maps to the class structure defined in the manifest) and calls -``evaluate``. - -Things are a bit messier than this in real life, but the summary is that -``evaluate`` retrieves the state of each object, compares that state to the -desired state, and creates a Puppet::StateChange object for every individual -bit that's out of sync (e.g., if a file has the wrong owner and wrong mode, -then each of those are in separate StateChange instances). The end result of -evaluating the whole tree is a collection of StateChange objects for every bit -that's out of sync, all sorted in order of dependencies so that objects are -always fixed before the objects that depend on them. - -The top-level component (which is also responsible for this sorting) creates a -Puppet::Transaction instance and inserts these changes into it. - -### Notes About Recursion - -Recursion muddies this phase considerably. While it's tempting to merely -handle recursion in the instantiation phase, the state on disk can (and will) -change between runs, so the configured state and the on-disk state must be -compared on every run (and it is assumed that ``puppetd`` will be a -long-running process that only does instantiation once but does configuration -many times). - -This means that there might still be objects that don't exist at the end of -instantiation but do exist at the end of comparison. In particular, when -doing recursive file copies from a remote machine, Puppet creates an object in -memory to map to every remote file, and that recursive object creation would -not make sense at instantiation time, only at comparison time. - -This might introduce some strangenesses, though, and it is expected that this -could cause interesting-in-a-not-particularly-good-way edge cases. - -## Configuration Phase 2: Syncing - -* *Inputs* [Puppet::Transaction][] instance containing [Puppet::StateChange][] - instances -* *Outputs* Completely configured operating system -* *Entry* [Puppet::Type::Component#evaluate][component_evaluate] -* *Exit* [Puppet::Transaction#evaluate][] - -The transaction's job is just to execute each change. The changes themselves -are responsible for logging everything that happens (one of the reasons that -all work is done by StateChange objects rather than just letting the objects -do it is to guarantee that every modification is logged). This execution is -done by calling ``go`` on each change in turn, and if the change does any work -then it produces an event of some kind. These events are collected until all -changes have been executed. - -Once the transaction is complete, all of the events are checked to see if -there are any callbacks associated with them. Puppet currently only supports -one type of callback and one way of specifying them: Calling ``refresh`` on -objects based on that object subscribing to another object. For instance, -take the following snippet: - - file { "/etc/ssh/sshd.conf": - source => "puppet://puppet/config/sshd.conf" - } - - service { sshd: - running => true, - subscribe => file["/etc/ssh/sshd.conf"] - } - -If the local file is out of sync with the remote file, then a StateChange -instance is created reflecting this. When that change is executed, it creates -a ``file_changed`` event. Because of the above subscription, the callback -associated with this event is to call ``refresh`` on the ``sshd`` service; for -services, ``refresh`` is equivalent to restarting, so sshd is restarted. In -this way, Puppet elements can react to changes that it makes to the system. - -While transactions are fully capable of moving both forward and backward -(e.g., if a transaction encountered an error, it could back out all of its -changes), there are currently no hooks within Puppet itself to specify when -and why that would happen. If this is a critical feature for you or you have -a brilliant way to go about creating it, I would love to hear it, but it is -currently a back-burner goal. - -# Conclusion - -That's the entire flow of how a Puppet manifest becomes a complete -configuration. There is more to the Puppet system, such as FileBuckets, but -those are more support staff rather than the main attraction. - -[facter]: /projects/facter -[parse]: /downloads/puppet/apidocs/classes/Puppet/Parser/Parser.html -[AST]: /downloads/puppet/apidocs/classes/Puppet/Parser/AST.html -[node elements]: /projects/puppet/documentation/structures.html#nodes -[yaml]: http://www.yaml.org/ -[Puppet::Parser::Parser#parse]: /downloads/puppet/apidocs/classes/Puppet/Parser/Parser.html -[ast_evaluate]: /downloads/puppet/apidocs/classes/Puppet/Parser/AST.html -[Puppet::Parser::Scope#to_trans]: /downloads/puppet/apidocs/classes/Puppet/Parser/Scope.html -[TransObject]: /downloads/puppet/apidocs/classes/Puppet/TransObject.html -[TransBucket]: /downloads/puppet/apidocs/classes/Puppet/TransBucket.html -[Puppet::Server::Master#getconfig]: /downloads/puppet/apidocs/classes/Puppet/Server/Master.html -[Puppet::Client::MasterClient#getconfig]: /downloads/puppet/apidocs/classes/Puppet/Client/MasterClient.html -[Transportable]: /downloads/puppet/apidocs/classes/Puppet/TransBucket.html -[Puppet::StateChange]: /downloads/puppet/apidocs/classes/Puppet/StateChange.html -[Puppet::Transaction]: /downloads/puppet/apidocs/classes/Puppet/Transaction.html -[Puppet::Client::MasterClient#apply]: /downloads/puppet/apidocs/classes/Puppet/Client/MasterClient.html -[component_evaluate]: /downloads/puppet/apidocs/classes/Puppet/Type/Component.html -[Puppet::Type::Component]: /downloads/puppet/apidocs/classes/Puppet/Type/Component.html -[Puppet::Transaction#evaluate]: /downloads/puppet/apidocs/classes/Puppet/Transaction.html -[interpreter]: /downloads/puppet/apidocs/classes/Puppet/Parser/Interpreter.html -[Puppet::Type]: /downloads/puppet/apidocs/classes/Puppet/Type.html -[Puppet::Type#finalize]: /downloads/puppet/apidocs/classes/Puppet/Type.html - -*$Id$* diff --git a/documentation/documentation/internals/index.page b/documentation/documentation/internals/index.page deleted file mode 100644 index 5a04ba6d5..000000000 --- a/documentation/documentation/internals/index.page +++ /dev/null @@ -1,16 +0,0 @@ ---- -inMenu: false -directoryName: Puppet Internals -title: Puppet Internals -orderInfo: 5 -subtreeLevel: 6 ---- - -Puppet Internals -===================== -* [The Big Picture](big-picture.html) -* [How it Works](howitworks.html) - - - -*$Id$* diff --git a/documentation/documentation/language/index.page b/documentation/documentation/language/index.page deleted file mode 100644 index fe37e6701..000000000 --- a/documentation/documentation/language/index.page +++ /dev/null @@ -1,18 +0,0 @@ ---- -inMenu: false -directoryName: Language Syntax -title: Language Syntax -orderInfo: 6 -subtreeLevel: 6 ---- - -Language Syntax -=============== - -* [Specifying Resources](resources.html) -* [Puppet Language Tutorial](tutorial.html) -* [Control Structures](structures.html) - - - -*$Id$* diff --git a/documentation/documentation/language/resources.page b/documentation/documentation/language/resources.page deleted file mode 100644 index ef0577e09..000000000 --- a/documentation/documentation/language/resources.page +++ /dev/null @@ -1,121 +0,0 @@ ---- -inMenu: true -title: Language Introduction -orderInfo: 30 ---- - -# Resources - -The fundamental building block in a Puppet configuration is called a -``resource``, which is just an object that models some element on a -computer. Each of these resources has a specific associated type, such -as ``user`` or ``package``, and each of these types has a fixed list of -allowed parameters (there are also -[metaparameters](../reference/typedocs.html#meta-parameters), which all -types accept). - -All resources also have a name that identifies them uniquely. - -Puppet provides a simple hash-like syntax for specifying resources; for -instance, here is how you might specify that a file should exist: - - file { "/etc/myfile": - content => "Some text", - mode => 644 - } - -Here we have the three key elements to any resource specification: The -type (``file``), the name (``/etc/file``), and an attribute list (in -this case, ``content`` and ``mode``). Multiple attributes must be -comma-separated, and trailing commas are acceptable. - -Whitespace generally doesn't matter; your resource can be specified on -one line, or split over several as above. - -## Multiple Resources - -You can just specify multiple resources one after the other in your -manifest: - - package { sudo: ensure => installed } - - file { "/etc/sudoers": mode => 440, owner => root } - -If you have many resources of the same type, you can semicolon-separate -them in one statement: - - file { - "/etc/passwd": owner => root, mode => 644; - "/etc/shadow": owner => root, mode => 440; - } - -Trailing semicolons are accepted, as you can see. - -If you have multiple resources of the same type and with the same -attribute list, you can use an array for the name: - - package { [openssh, openssl]: ensure => installed } - -## Relationships - -No resource lives in a vacuum -- resources usually work together to -provide some needed functionality. Puppet provides some facilities for -specifying that resources are related, and specifying these -relationships provides some extra functionality. - -There are two kinds of relationships in Puppet -- normal dependency, and -reactive dependency -- and you can specify them from either end of the -relationship. Because any resource can be related to any other -resource, relationships are specified with -[metaparameters](../reference/typedocs.html#meta-parameters). - -Normal dependency relationships are just used for ordering; as long as -you do not create circular dependencies, Puppet guarantees that your -resources will be configured in the order of their dependencies. For -instance: - - user { myuser: ensure => present } - - file { "/tmp/file": - owner => myuser, - ensure => directory - require => User[myuser] - } - -Notice how the dependency is specified -- this is called a ``resource -reference``, and is composed of the type and name of the related -resource. Puppet operations on types are capitalized, and in this case -you are essentially treating the type as a hash and looking an instance -up by name. - -Reactive dependencies provide the same ordering relationship as normal -dependencies, and in addition the dependency attempts to react to any -changes in required resources. Most resource types are not capable of -reacting to anything (e.g., users do not need to be restarted, nor do -files need to get refreshed), but this is an important functionality -for resources like ``service``. - -Plain dependencies are specified using ``require`` and ``before``, while -reactive dependencies are specified using ``subscribe`` and ``notify``. - -It is important to always specify your relationships and not to depend -on file order, because Puppet does a topological sort of all resources -based on relationship, and resources that are not guaranteed to stay in -the same order in which they are specified. - -### Autorequire - -The above example is actually redundant, because Puppet makes every -attempt to automatically determine relationships. The ``file`` resource -is smart enough to automatically list any associated users or groups as -dependencies, for instance. In most cases, Puppet resources are smart -enough to autorequire any directly related resources. - -### Syntax vs. Attributes - -It is important to note that Puppet's interpreter only validates that -attributes are valid for the associated type, it never interprets their -values in any way. A resource specification that successfully compiles -for a client may fail to pass validation on that client, for instance. - -*$Id$ diff --git a/documentation/documentation/language/structures.page b/documentation/documentation/language/structures.page deleted file mode 100644 index b015b9fe1..000000000 --- a/documentation/documentation/language/structures.page +++ /dev/null @@ -1,330 +0,0 @@ ---- -inMenu: true -title: Control Structures -orderInfo: 30 ---- - -This is a brief overview of the language structures available for making site -configurations in Puppet. For futher documentation, visit the -[Puppet homepage](/projects/puppet/). - -# Importing Manifests - - import "filename" - -Starts the parsing of the file specified and creates any specified definitions -and classes at the current scope. Currently files are only searched for -within the same directory as the file doing the importing. - -Files can also be imported using globbing, as implemented by -Ruby's ``Dir.glob`` method: - - import "classes/*" - import "packages/[a-z]*" - -# Scope - -Generally speaking, any language structure that involves curly braces creates -a new scope inside those braces. This currently includes server and class -definitions and if/then/else structures. Each file should also introduce its -own scope but currently does not. - -Once assigned, variables cannot be reassigned within the same scope. However, -within a sub-scope a new assignment can be made for a variable name for that -sub-scope and any further scopes created within it: - - $var = value - - # override $var - define testing { - $var = othervalue - } - -Service and class definitions are scoped just as variable assignments are. -Functions defined and Classes created within a scope will not be available -outside the scope in which they are created: - - define testing { - file { "/etc/passwd": owner => root } - } - - class osx { - # override the existing testing definition - define testing { - file { "/etc/other": owner => root } - } - } - -The evaluation by Puppet of following example would be result in the copying -of ``/file_repository/test-httpd.conf`` to ``/etc/httpd/conf/httpd.conf``: - - $filename = "/etc/apache/httpd.conf" - - class webserver { - $filename = "/etc/httpd/conf/httpd.conf" - define httpd_service (config_file) { - file { $filename : source => $config_file } - } - httpd_service { "test_httpd" : - config_file => "/file_repository/test-httpd.conf" - } - } - - webserver {} - -# Components - - define <name>(<param1>,<param2>,...) {...} - -Definition of fuctions allows the composition of lower level types into higher -level types. - -Parameters of defined functions can be referenced within the definition scope, -similarly to variables, by preceding their names with the ``$`` character: - - define svnserve($source, $path, $user = false, $password = false) { - file { $path: - create => directory, - owner => root, - group => root - } - $svncmd = $user ? { - false => "/usr/bin/svn co --non-interactive $source/$name .", - default => "/usr/bin/svn co --non-interactive --username $user --password '$password' $source/$name ." - } - exec { $svncmd: - cwd => $path, - require => file[$path], - creates => "$path/.svn" - } - } - - svnserve { dist: - source => "https://reductivelabs.com/svn", - path => "/dist", - user => "puppet", - password => "password" - } - - svnserve { "dist/config/apps/puppet": - source => "https://reductivelabs.com/svn", - path => "/etc/puppet", - user => "puppet", - password => "password" - } - -As of 0.19.0, arguments in definition prototypes must have '$' attached to them. - -Note that calling components results in a unique instance of all contained -objects. In the above case, each of the calls to ``svnserver`` results in -an ``exec`` and a ``file`` instance. So, it's important that all of your -components are written that they support this. - -A good rule of thumb is that you should only include statements in your -components that have variables in their names. If a statement doesn't -have a variable in the name, then you are likely to result in a situation -where multiple components will try to manage the same instance, which will -result in an error at run time. - -## $name - -Within a component, the name used in the component is available via the -``$name`` variable. This is very similar to the concept of ``self`` in -many OO languages, but it's just a simple text string, not a reference -to an object or something. - -# Server Classes - - class <class_name> [inherits <super_class_name>] { ... } - -Class definitions allow the specification of a hierarchy of server classes; a -host that is a member of a subclass will apply the configuration from the -subclass and all parent classes. The primary difference between classes and -components is that classes are singletons -- there will only ever be a single -instance of a given class on a given server. Thus, if you have a server which -is a member of three different classes, each of which share the same parent -class, then you will get one instance of the parent class and one instance of -each of the subclasses. - - # really simple example - class solaris { - file { - "/etc/passwd": owner => root, group => root, mode => 644; - "/etc/shadow": owner => root, group => root, mode => 440 - } - } - - class solworkstation inherits solaris { - file { - "/etc/sudoers": owner => root, group => root, mode => 440; - "/bin/sudo": owner => root, group => root, mode => 4111 - } - } - - include solworkstation - -Because ``include`` is a function, any normal value can be used, including -variables and selectors: - - include $operatingsystem, $hostname ? { - myhost => classA, default => classB - } - -## <a name="classes-vs-components">Classes vs. Components</a> - -Classes and components are defined similarly (although classes currently -do not accept parameters), but they are meant to be used very -differently. Components are used to define reusable objects which will -have multiple instances on a given host, so they cannot include any -elements that will only have one instance, such as a package or a -root-level service. Classes, on the other hand, are guaranteed to be -singletons -- you can include them as many times as you want and you'll -only ever get one copy of the elements -- so they are exactly meant to -include these singleton objects. - -Most often, services will be defined in a class, where the service's -package, configuration files, and running service will all be defined -in the class, because there will normally be one copy of each on a given -host. Components would be used to manage elements like virtual hosts, -of which you can have many, or to encode some simple information in a -reusable wrapper to save typing. Every installation I've done of Puppet -so far has a ``remotefile`` component that encodes where Puppet clients -should get their configuration files from: - - define remotefile(source, owner = root, group = root, recurse = true) { - file { $name: - source => "http://puppet.$domain/dist/$source", - owner => $owner, - group => $group, - recurse => $recurse - } - } - -## Subclassing - -The primary benefit of using subclasses instead of just including the parent -class is that the subclass can override elements in the parent class: - - class unix { - file { "/etc/sudoers": - owner => root, - group => root, - mode => 440 - } - } - - class bsd inherits unix { - file { "/etc/sudoers": - group => wheel - } - } - -Including the ``unix`` class sets the group to ``root``, but including the -``bsd`` class overrides the vale to ``wheel``. - -## Using Classes Outside of Puppet - -This isn't really a "language" thing, but it seemed the best place to document -this. - -All classes set on a Puppet client are stored in an external file (usually -``/etc/puppet/classes.txt``, but can be modified with the ``classfile`` -argument or setting). This means other tools can easily read in the classes -that Puppet sets and use them for their own logic. - -There is also (as of 0.15.4) a new command to set arbitrary classes that do -not have any code associated with them: - - class freebsd { - tag unix, bsd - } - - class redhat { - tag unix, sysv - } - -These classes will then be written to the classes.txt file like all others, -even though there is no code associated with them. The syntax is just like -``include``, so you can use variables, also: - - tag $operatingsystem - -<h1><a name="nodes">Nodes</a></h1> - - node <hostname> { ... } - -Node definitions specify the configuration to apply to a specific node. By -default they are looked for by ``puppetmasterd`` but not by ``puppet``. See -the documentation for each to enable or disable them. - -Any code outside of a node definition will be applied to all nodes, while any -code inside will only apply to the specified node or nodes: - - class webserver { ... } - class dbserver { ... } - - file { "/etc/sudoers": mode => 440 } # apply to everyone - - node host1, host2 { - include webserver - } - node host3, host4 { - include dbserver - } - -Nodes can also inherit from other nodes, so it's easy to apply defaults: - - node base { - include $operatingsystem - } - - node kirby inherits base { - include webserver - } - -You can specify fully-qualified node names, but you have to single-quote the -names: - - node 'host.domain.com' { - ... - } - -# Conditionals - -Puppet currently supports two types of conditionals: in-statement and around -statements. We call the in-statement conditionals ``selectors``, as they are -essentially a select-style operator, which support the use of ``default`` to -specify a default value: - - define testing(os) { - owner = $os ? { - sunos => adm, - redhat => bin, - default => root - } - file { "/some/file": owner => $owner } - } - - - -The ``case`` statement provides the ability to conditionally apply -types: - - case $operatingsystem { - sunos: { solaris {} } # apply the solaris class - redhat: { redhat {} } # apply the redhat class - default: { generic {} } # apply the generic class - } - -# Reserved words - -Generally, any word that the syntax uses for special meaning is probably also -a reserved word, meaning you cannot use it for variable or type names. Thus, -words like ``true``, ``define``, ``inherits``, and ``class`` are all reserved. - -# Comments - -Puppet supports sh-style comments; they can either be on their own line or at -the end of a line (see the Conditionals example above). - -*$Id$* diff --git a/documentation/documentation/language/tutorial.page b/documentation/documentation/language/tutorial.page deleted file mode 100644 index 461c92e70..000000000 --- a/documentation/documentation/language/tutorial.page +++ /dev/null @@ -1,190 +0,0 @@ ---- -inMenu: true -title: Puppet Language Tutorial -orderInfo: 30 ---- - -# 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. - -## Variable Interpolation - -Variables will get interpolated within double-quoted strings by default. You -can disable the interpolation by escaping the dollar sign: - - $str = "A string with a \$dollar sign in it" - -During interpolation, you can also surround your variable with curly braces if -necessary: - - $a = "something" - $b = "else" - $c = "${a}_${b}" - -# Fact Variables (facts) - -In addition to variables that are manually assigned (as above), `puppet` also -uses the [facter](/projects/facter/index.html) utility to glean information -about the system. The facts gleaned by `facter` are made available as -variables for use in `puppet`. - -You can get a full listing of variables that should be set by `puppet` from -`facter` facts by running the `facter` command with no arguments, for instance: - - $ facter - rubysitedir => /usr/lib/ruby/site_ruby/1.8 - operatingsystemrelease => 8.8.0 - hardwaremodel => Power Macintosh - ipaddress => 10.10.10.52 - kernelrelease => 8.8.0 - facterversion => 1.3.3 - operatingsystem => Darwin - macaddress => 00:0d:de:ad:be:ef - -# 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 } - } - } - - ... - -*$Id$* diff --git a/documentation/documentation/programmers/creating-a-puppet-type.page b/documentation/documentation/programmers/creating-a-puppet-type.page deleted file mode 100644 index fcf2ea011..000000000 --- a/documentation/documentation/programmers/creating-a-puppet-type.page +++ /dev/null @@ -1,384 +0,0 @@ ---- -inMenu: true -title: Creating Custom Types -orderInfo: 70 ---- - -# Organizational Principles - -I won't claim that the terminology currently in place is great, but it's -what's there, so bear with me. - -Puppet types are basically container classes; they do not directly do any work -themselves, usually, but rather serve to collect other classes that can work. -The three types of classes that a type can contain are Parameters_, -MetaParameters_, and States_. - -Types are created by calling the ``newtype`` method on ``Puppet::Type``, with -the name of the type as the only required argument (you can optionally specify -a parent class; otherwise, Puppet::Type is used as the parent class), and you -must also provide a block of code used to define the type: - - Puppet::Type.newtype(:database) do - ... the code ... - end - -A normal type would define multiple states and zero or more parameters. -Once these are defined, you just put the type into ``lib/puppet/type`` -anywhere in Ruby's search path, and Puppet will autoload the type when you use -it in the language. - -All types should also provide inline documention in the ``@doc`` class -instance variable. The text format is in Restructured Text. - -## Parameters - -These are usually simple attributes that can be used to modify function, but -they don't directly do any work themselves. Parameters are defined inside the -block passed to ``newtype``, using the ``newparam`` method: - - Puppet::Type.newtype(:database) do - newparam(:color) do - desc "Specify the color you want your database to be." - - newvalues(:red, :green, :blue, :purple) - end - end - -The ``desc`` method provides documentation for your parameter. This -documentation is used by ``puppetdoc`` to create the -[Type Reference](../reference/typedocs.html). - -The ``newvalues`` method is optional; if you use it, then only those values -(in string or symbol form) will be considered valid values, and they will -always be converted to symbols for easier testing. - -At least one of your parameters must be the **namevar**, specified using the -``isnamevar`` method. This is a too-magical parameter in Puppet; this is the -attribute that is considered to uniquely identify a given instance, such as a -file's path or a user's name. If a separate name is not provided, then this -value is returned by the ``name`` method on a type instance, but you can -specify both a name and the namevar, although it can be confusing internally: - - file { sshconfig: - path => "/etc/ssh/ssh_config", - source => "/nfs/path/to/my/ssh/config" - } - -This would have ``file.name`` returning ``sshconfig`` and ``file[:path]`` -returning ``/etc/ssh/ssh_config``. This is confusing enough that it's best to -always use the namevar and not the ``name`` method. - -You can specify regexes in addition to literal values; matches against regexes -always happen after equality comparisons against literal values, and those -matches are not converted to symbols. For instance, given the following -definition: - - newparam(:color) do - desc "Your color, and stuff." - - newvalues(:blue, :red, /.+/) - end - -If you provide "blue" as the value, then your parameter will get set to -``:blue``, but if you provide "green", then it will get set to "green". - -Currently, you set parameters by treating the containing object as a hash: - - db[:color] = :blue - -If the parameter already exists, then 'value=' is called on the object, with -the value you provide. If it does not exist, then the object is created and -put into the type instance's ``@parameters`` hash, indexed by parameter name. -The parameter object gets its ``@parent`` instance variable set so that it -points back to the containing type instance. - -You can similarly retrieve the parameter: - - puts db[:color] - -Within the type instance itself (i.e., in instance methods), you can use these -same methods to set and retrieve the values, or you can call the ``value`` -methods directly, once the object exists: - - # Create the param - self[:color] = :blue - color = @parameters[:color].value - @parameters[:color].value = :red - -### Validation and Munging - -If your parameter does not have a defined list of values, or you need to -convert the values in some way, you can use the ``validate`` and ``munge`` -hooks: - - newparam(:color) do - desc "Your color, and stuff." - - newvalues(:blue, :red, /.+/) - - validate do |value| - if value == "green" - raise ArgumentError, - "Everyone knows green databases don't have enough RAM" - else - super - end - end - - munge do |value| - case value - when :mauve, :violet # are these colors really any different? - :purple - else - super - end - end - end - -These should probably not be methods you call on the type and should just be -instance methods you define, but it's not a big deal either way. The default -``validate`` method looks for values defined using ``newvalues`` and if there -are any values defined it accepts only those values (this is exactly how -allowed values are validated). The default ``munge`` method converts any -values that are specifically allowed into symbols. If you override either of -these methods, note that you lose this value handling and symbol conversion, -which you'll have to call ``super`` for. - -Values are always validated before they're munged. - -Lastly, validation and munging *only* happen when a value is assigned. They -have no role to play at all during use of a given value, only during -assignment. - -## MetaParameters - -These are just like parameters in all but two ways. First, they are defined -using the ``newmetaparam`` method, and second, when defined they are valid for -all types, not just a single type. See the end of type.rb for examples. - -You should never define any of these in an average custom type; if you need a -new MetaParameter, contact the main developers about getting it added to the -core. - -## States - -States are what usually do the actual work on the system. These are actually -a subclass of parameters, but with much more functionality. Without -exception, every state needs to define at least two methods: ``retrieve`` and -``sync``. - -### The Variables - -The ``retrieve`` and ``sync`` methods work in tandem with two important -instance variables, ``@is`` and ``@should``. The first should reflect the -current state of the, um, state (I already admitted the nomenclature is bad), -and it should be in whatever form your class expects -- symbol, array, -whatever. The second reflects what the current state, um, should be, and it -is *always* an array. - -Because there are two variables that contain values, assignment to states is a -bit odd. By default, ``@should`` is used when you use the indexing methods: - - file[:owner] = "root" - -This sets ``@should`` to be ``["owner"]``. You would not normally set the -``@is`` variable from outside the instance, but sometimes it's necessary: - - file.is = [:owner, "root"] - -Because ``@should`` is always an array but most states can't actually use -an array, the ``should`` accessor method only returns the first value in the -array. If you do want to use the whole array (i.e., you consume all of the -values, not just the first), then you have to override the ``should`` method -to return the whole array. You'll see why in a minute. - -I should probably explain why ``@should`` is always an array: You can always -specify multiple values for any state, and by default, if the current state is -in that list of values, then no work is done. That is, given the following -definition: - - file { "/etc/sudoers": - owner => root, group => [wheel, root], mode => 440 - } - -If the group is currently ``wheel`` or ``root``, then the file is considered -in sync. - -### The Methods - -The ``retrieve`` method is used to get the current value of the state on the -machine. For instance, here is a trivialized version of how to retrieve a -File's owner: - - newstate(:owner) do - def retrieve - @is = File.stat(@parent[:path]).mode - end - end - -It's critical that you set the ``@is`` instance variable on the state. -Puppet should really just set the variable for you based on the return value, -but, well, it doesn't do that right. One important aspect of ``retrieve`` is -that it should not modify the system in any way; if someone runs their -configuration in ``noop`` mode, then ``retrieve`` is still called, so it's -important that it not modify the state of the system. - -The other critical method is ``sync``, which actually modifies the machine: - - newstate(:owner) do - def retrieve - @is = File.stat(@parent[:path]).uid - end - - def sync - File.chown(self.should, nil, @parent[:path]) - - return :file_changed - end - end - -Note this ``return`` here; sync operations are expected to return an event if -they do any work, and this event is used to trigger subscribing objects. If -you return nil, then Puppet will assume you didn't do any work. At this point -the events themselves are meaningless, but at some point users will be able to -subscribe to specific events, rather than all events from a given object. - -There's a third method, ``insync?``, which you will not normally override but -is important to understand. This method is used to determine if your state is -in sync, and thus if any work needs to be done. The default method looks a -lot like this: - - def insync? - @should.include?(@is) - end - -Notice that we're checking to see if our current value is anywhere in the -``@should`` list. - -### State Values - -Just like parameters, you can define allowed values for states, but there's -one significant change: With state values, you have to specify the code that -will achieve that state. Here is a trivialized version of ``ensure`` state on -files: - - newstate(:ensure) do - newvalue(:file) do - @parent.write { |f| f.puts "" } # make an empty file - return :file_created - end - - newvalue(:directory) do - Dir.mkdir(@parent[:path]) - return :directory_created - end - - newvalue(:absent) do - File.unlink(@parent) - return :file_deleted - end - - # Allow users to treat these equivalently. - aliasvalue(:present, :file) - end - -You similarly must provide code when you specify a regular expression. This -value specification mechanism gives you the same validation and munging that -parameters have while allowing you to cleanly separate your code for each -allowed value. See the existing types for examples of this, although not all -states have a defined value list, and this mechanism was created long after -most of the types were created and they have not all been updated to use it. - -Behind the scenese, puppet creates a ``set_<value>`` method, named for each -allowed value, and the default ``sync`` method just looks at the ``should`` -value here, tries to find an appropriate method, and calls it if it finds -one. In this example, files have ``set_file``, ``set_directory``, and -``set_absent`` methods, and ``sync`` calls them according to the output of -``should``. - -All of these are convenience methods, of course; you can have a single opaque -all-powerful ``sync`` method, you don't have to split it up using values. - -# Process - -Now that you have an idea of how types are constructed, let's look at the -process of applying one or more type instances. - -## Dependency Sorting - -I'll ignore the process of turning Puppet manifests into types; that's handled -in the [How It Works](../internals/howitworks.html) document. The collection of objects -are always contained in a top-level instance of the ``component`` type (this -is an unfortunate hold-over from some flawed design ideas in the early -development of Puppet -- expect it to change internally at some point). - -When work is begun, ``evaluate`` is called on the component (usually by -client/master.rb); this method does a topological sort based on dependency -information on all contained objects (components can contain other components, -so it's a recursive sort), creates a new transaction, and adds the now-sorted -flat list of objects to the transaction. - -## Transactions - -Once the transaction has all of the objects, ``evaluate`` is called on it. -This method is the heart of action in Puppet; it's relatively short, but -determines all of the actual function in a given run. - -It iterates across the sorted list of objects, finding all objects that are -scheduled to run (which, by default, is all of them) and that match the tag -list if there are any tags specified (you can specify tags to ``puppetd`` -which will cause it to only run objects that have those tags). For each of -those found objects, the transaction calls ``evaluate`` on the object, which -in turn calls ``statechanges`` on the object. - -The ``statechanges`` method iterates across each instantiated state (i.e., -file objects have many states, but only those states for which you've provided -a value have instances in a given file object's ``@states`` variables), -looking for out-of-sync states. The states are checked in the order they're -defined; this often does not matter, but for classes like ``file`` it matters -a lot. For each state that's out of sync, a ``StateChange`` object is -created; it's basically an organizational class that knows how to sync a state -and log the work it's doing. - -There's one exception to this "all states are checked" rule: If the instance -has an ``ensure`` state and that state is out of sync, then Puppet assumes -that the object is entirely missing or will be entirely removed and that the -``ensure`` state knows how to do that. This allows Puppet to create just one -log message when creating a new object (as opposed to, say, one each for the -file contents, the mode, the owner, and the group) and provides better -modeling for object creation and destruction. However, it does mean that if -you provide this state it needs to be able to completely create the object on -its own; this often just means syncing all of the other out-of-sync states -once the object exists. - -The type instance's ``evaluate`` method returns to the transaction the list of -collected state change objects. Once the transaction has all of the changes, -it iterates across each one, calling ``forward`` on them (yes, there's a -``backward`` that can revert the change) and collecting events from each -change. - -Until recently, Puppet collected all of the events (which contain references -to the object that generated them) and triggered any subscriptions at the end -of the run, but now events are managed so that they're triggered inline. - -Once all of an object's states are in sync, the transaction looks for events -that the object is subscribed to and triggers any found subscriptions. - -That's pretty much it. The ``transaction`` class is pretty short, but it's -also pretty complicated. Fortunately, you should be able to ignore it just -about entirely; define your states in the order you want them applied, make -sure your ``ensure`` state can completely create or destroy the object, and -return events if you made a change. Other than that, you should not have to -think about transactions or how they work. - -# Conclusion - -That's all you need for your type. See the existing types for different ways -to treat this. You can create methods on your type and call those methods -from the state (like packages do), or put enough complexity into each state -that they end up in their own file (like files do). - -Comments on this document are appreciated. - -*$Id$* diff --git a/documentation/documentation/programmers/index.page b/documentation/documentation/programmers/index.page deleted file mode 100644 index db8bccfbe..000000000 --- a/documentation/documentation/programmers/index.page +++ /dev/null @@ -1,14 +0,0 @@ ---- -inMenu: false -directoryName: Programmer's Reference -title: Programmer's Reference -orderInfo: 7 -subtreeLevel: 6 ---- - -Programmer's Reference -====================== -* [Creating a Puppet Type](creating-a-puppet-type.html) -* [About Providers](providers.html) - -*$Id$* diff --git a/documentation/documentation/programmers/providers.page b/documentation/documentation/programmers/providers.page deleted file mode 100644 index f8b2c1379..000000000 --- a/documentation/documentation/programmers/providers.page +++ /dev/null @@ -1,169 +0,0 @@ ---- -inMenu: true -title: Providers -orderInfo: 70 ---- - -# Providers - -One of Puppet's primary goals is to function as a portable abstraction -layer above different operating systems, relieving developers and users -from the need to know how to use every command on every operating -system. The top layer of the abstraction layer is composed of Puppet -types, such as Users, Groups, and Packages; these types provide the -modeling for how to manage a given resource, such as what attributes are -appropriate and how to validate them. - -For some resource types and on some platforms, simple types are -sufficient. In the far more common case, though, types must be -implemented differently on different platforms, and a layer exists below -the types to handle this implementation variety. This layer is composed -of what we call ``providers``. For example, Puppet currently supports -more than 15 different package providers, such as ``apt``, ``yum``, and -``gem``. Puppet will usually select an appropriate provider for your -system, but you can override that default selection using the -``provider`` attribute as appropriate. - -This document is meant to help you understand how to create new -providers. They are usually quite simple, and they are a great way to -get started with Puppet development. Puppet automatically loads -providers on demand, so you can create a new provider, drop it into your -Ruby search path, and start using it immediately. We are also always -glad to add new providers to the main Puppet distribution. - -Puppet types are not required to have providers, and not all of the core -types that ship with Puppet have yet been converted to using them, but -it is our goal to do so, and it is recommended that all new types split -the modeling and implementation into types and providers. - -Any type that does have providers will automatically have a ``provider`` -attribute created, and this attribute can be used to specify the -provider; otherwise, Puppet will try to determine the appropriate one. - -## Provider Suitability - -Providers are inherently tied to a given platform or a given tool, so -the majority of providers will usually not be suitable on a given -system. To handle this fact, Puppet provides mechanisms for confining -providers based on their requirements. You can confine providers to -specific platforms according to facts returned by Facter, but it is -usually best to confine them based on what binaries they require to -function. - -Confinement is accomplished using two provider class methods: -``commands`` and ``confine``. - -### Confinement - -The most important method is ``confine``, and in fact it's used by -``commands``. It supports four criteria for determining suitability: -Existence of a file, truth of a value, falseness of a value, or whether -a fact matches. Generally the true and false tests are used in -combination with another statement; for instance, you could try to load -a library, set a value based on the results of the load, and then -confine a provider based on the value. - -The ``exists`` test is mostly useful for checking for binaries, so it is -better to use the ``commands`` method in those cases as it is more -useful. - -Any ``confine`` arguments that are not ``true``, ``false``, or -``exists`` are expected to be Facter facts, with a single value or an -array of values to test against. If the host's value for that fact is -not in the list of provided values, then the host is not suitable. Fact -names and values can be passed as strings or symbols of any case. - -Here is an example using all of the tests: - - confine :exists => "/etc/pam.d" - confine :true => defined?(ActiveRecord) - confine :false => defined?(OtherClass) - confine :operatingsystem => [:darwin, :solaris] - -### Commands - -You specify the binaries that your provider needs using the ``commands`` -method; for example, this is how the ``apt`` provider confines itself to -appropriate systems: - - commands :aptget => "/usr/bin/apt-get", - :aptcache => "/usr/bin/apt-cache", - :preseed => "/usr/bin/debconf-set-selections" - -This method does two things for you: It calls ``confine`` with the -binary as an ``exists`` test, and it stores the value in a place that -instances can easily access it. Instances can call ``command`` with the -name you use and get the full path back: - - execute(command(:aptget), "install", "mypkg") - -Even more usefully, though, this defines an instance method with the -name you use, so you can just call this instead: - - aptget "install", "mypkg" - -When you use ``commands``, you can choose whether your binary is -specified fully qualifed or unqualified. If you do not qualify the -binary, then the provider is suitable as long as the binary is somewhere -in Puppet's search path; if the binary is fully qualified, then it must -exist at exactly that location. - -### Defaults - -Because hosts might often have multiple suitable providers for a given -type, you can specify that a provider is a default, based again on fact -comparisons: - - defaultfor :operatingsystem => :debian - -Puppet will use the longest matching list of defaults to select a -provider, so the following provider would be chosen in preference to the -above provider: - - defaultfor :operatingsystem => :debian, :hardwaremodel => "i386" - -## Provider APIs - -Providers only ever interact with an instance of its associated type, so -the only class that needs to know the provider API is that associated -type. Puppet defaults to a simple API based on attributes, but the type -can override if appropriate. Unless you are creating a new Puppet type, -the best way to determine what your provider API is usually to look at -other providers. - -By default, Puppet will just call setter and getter methods on the -provider according to the attributes being modified. For instance, -``user`` providers define ``uid=`` and ``uid`` methods, and the ``user`` -type calls these methods to modify a user's UID. If this API is -appropriate for your type, then you just need to implement the -validation and documentation in your type, and the provider will do the -rest. - -If this API is not appropriate, however, as in packages and services, -then you can define a custom API. Generally you would implement this by -calling different provider methods for different values; here is a -snippet of how the ``package`` provider interface is called: - - newvalue(:present, :event => :package_installed) do - provider.install - end - -Here, the type supports multiple values for the ``ensure`` state, and -each value results in a different method being called on the provider. - -## Documentation - -Providers, like many other aspects of Puppet, can provide a -documentation string (in Markdown) to describe how to use them. When -the Type reference is generated, all providers will be listed for each -type, along with each provider's doc string, the list of binaries it -requires, and for what systems it is a default. - -This doc string is specified using the ``desc`` class method: - - Puppet::Type.type(:package).provide :apt do - desc "The apt provider." - ... - end - -# $Id$ diff --git a/documentation/documentation/reference/index.page b/documentation/documentation/reference/index.page deleted file mode 100644 index 21b054976..000000000 --- a/documentation/documentation/reference/index.page +++ /dev/null @@ -1,18 +0,0 @@ ---- -inMenu: false -directoryName: Reference -title: Reference -orderInfo: 4 -subtreeLevel: 6 ---- - -Reference -========= -* [Configuration Parameter Reference](configref.html) -* [Function Reference](functions.html) -* [Reports Reference](reports.html) -* [Type Reference](typedocs.html) - - - -*$Id$* diff --git a/documentation/documentation/reference/reports.header b/documentation/documentation/reports.header index f919a1aca..f919a1aca 100644 --- a/documentation/documentation/reference/reports.header +++ b/documentation/documentation/reports.header diff --git a/documentation/documentation/reference/reports.page b/documentation/documentation/reports.page index 5b0f2b3b7..5b0f2b3b7 100644 --- a/documentation/documentation/reference/reports.page +++ b/documentation/documentation/reports.page diff --git a/documentation/documentation/reference/typedocs.header b/documentation/documentation/typedocs.header index 69fabd07c..69fabd07c 100644 --- a/documentation/documentation/reference/typedocs.header +++ b/documentation/documentation/typedocs.header diff --git a/documentation/documentation/reference/typedocs.page b/documentation/documentation/typedocs.page index 18d7d3163..18d7d3163 100644 --- a/documentation/documentation/reference/typedocs.page +++ b/documentation/documentation/typedocs.page diff --git a/documentation/faq.page b/documentation/faq.page index f8455bcb1..83a83dca6 100644 --- a/documentation/faq.page +++ b/documentation/faq.page @@ -226,9 +226,9 @@ openssl: [Installation Guide]: documentation/installation.html [How Puppet Compares to Cfengine]: documentation/notcfengine.html [GNU Public License]: http://www.gnu.org/copyleft/gpl.html -[examples]: /cgi-bin/puppet.cgi/browser/trunk/examples/code/ +[examples]: /trac/puppet/browser/trunk/examples/code/ [unit testing]: http://www.pragmaticprogrammer.com/starter_kit/ut/ -[bug database]: /cgi-bin/puppet.cgi/report +[bug database]: /trac/puppet/report [reference]: documentation/typedocs.html [download]: /downloads [thread]: http://mail.madstop.com/pipermail/puppet-dev/2006-April/000393.html diff --git a/documentation/index.page b/documentation/index.page index 0e00a66e0..7cf31ab2a 100644 --- a/documentation/index.page +++ b/documentation/index.page @@ -23,7 +23,7 @@ Puppet's primary author, Luke Kanies, is usually online there. ## Relevant Links -* [Documentation](documentation/) +* [Documentation](/trac/puppet/wiki/DocumentationStart) Available documentation on puppet. Including an Introduction, and Language & Type Library References. @@ -45,7 +45,7 @@ Puppet's primary author, Luke Kanies, is usually online there. Puppet Subversion Repository -* [Bug Tracker](/cgi-bin/puppet.cgi) +* [Bug Tracker](https://reductivelabs.com/trac/puppet) Bug tickets, feature enhancements, and source browsing |