doc -> docs (pypi)

Signed-off-by: Nico Schottelius <nico@brief.schottelius.org>
This commit is contained in:
Nico Schottelius 2012-10-25 17:17:52 +02:00
commit 6d1e4d06cf
133 changed files with 12 additions and 12 deletions

210
docs/man/cdist-reference.text.sh Executable file
View file

@ -0,0 +1,210 @@
#!/bin/sh
#
# 2010-2012 Nico Schottelius (nico-cdist at schottelius.org)
#
# This file is part of cdist.
#
# cdist is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# cdist is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with cdist. If not, see <http://www.gnu.org/licenses/>.
#
#
# Generate manpage that lists available types
#
__cdist_pwd="$(pwd -P)"
__cdist_mydir="${0%/*}";
__cdist_abs_mydir="$(cd "$__cdist_mydir" && pwd -P)"
__cdist_myname=${0##*/};
__cdist_abs_myname="$__cdist_abs_mydir/$__cdist_myname"
filename="${__cdist_myname%.sh}"
dest="$__cdist_abs_mydir/man7/$filename"
cd "$__cdist_abs_mydir"
exec > "$dest"
cat << eof
cdist-reference(7)
==================
Nico Schottelius <nico-cdist--@--schottelius.org>
NAME
----
cdist-reference - Variable, path and type reference for cdist
EXPLORERS
---------
The following global explorers are available:
eof
(
cd ../../conf/explorer
for explorer in *; do
echo "- $explorer"
done
)
cat << eof
PATHS
-----
If not specified otherwise, all paths are relative to the checkout directory.
conf/::
Contains the (static) configuration like manifests, types and explorers.
conf/manifest/init::
This is the central entry point.
It is an executable (+x bit set) shell script that can use
values from the explorers to decide which configuration to create
for the specified target host.
Its intent is to used to define mapping from configurations to hosts.
conf/manifest/*::
All other files in this directory are not directly used by cdist, but you
can seperate configuration mappings, if you have a lot of code in the
conf/manifest/init file. This may also be helpful to have different admins
maintain different groups of hosts.
conf/explorer/<name>::
Contains explorers to be run on the target hosts, see cdist-explorer(7).
conf/type/::
Contains all available types, which are used to provide
some kind of functionality. See cdist-type(7).
conf/type/<name>/::
Home of the type <name>.
This directory is referenced by the variable __type (see below).
conf/type/<name>/man.text::
Manpage in Asciidoc format (required for inclusion into upstream)
conf/type/<name>/manifest::
Used to generate additional objects from a type.
conf/type/<name>/gencode-local::
Used to generate code to be executed on the source host
conf/type/<name>/gencode-remote::
Used to generate code to be executed on the target host
conf/type/<name>/parameter/required::
Parameters required by type, \n seperated list.
conf/type/<name>/parameter/optional::
Parameters optionally accepted by type, \n seperated list.
conf/type/<name>/parameter/boolean::
Boolean parameters accepted by type, \n seperated list.
conf/type/<name>/explorer::
Location of the type specific explorers.
This directory is referenced by the variable __type_explorer (see below).
See cdist-explorer(7).
out/::
This directory contains output of cdist and is usually located
in a temporary directory and thus will be removed after the run.
This directory is referenced by the variable __global (see below).
out/explorer::
Output of general explorers.
out/object::
Objects created for the host.
out/object/<object>::
Contains all object specific information.
This directory is referenced by the variable __object (see below).
out/object/<object>/explorers::
Output of type specific explorers, per object.
TYPES
-----
The following types are available:
eof
for type in man7/cdist-type__*.text; do
no_dir="${type#man7/}";
no_type="${no_dir#cdist-type}";
name="${no_type%.text}";
name_no_underline="$(echo $name | sed 's/^__/\\__/g')"
man="${no_dir%.text}(7)"
echo "- $name_no_underline" "($man)"
done
cat << eof
OBJECTS
-------
For object to object communication and tests, the following paths are
usable within a object directory:
changed::
This empty file exists in an object directory, if the object has
code to be excuted (either remote or local)
ENVIRONMENT VARIABLES
---------------------
__explorer::
Directory that contains all global explorers.
Available for: explorer, type explorer
__manifest::
Directory that contains the initial manifest.
Available for: initial manifest, type manifest
__global::
Directory that contains generic output like explorer.
Available for: initial manifest, type manifest, type gencode
__object::
Directory that contains the current object.
Available for: type manifest, type explorer, type gencode
__object_id::
The type unique object id.
Available for: type manifest, type explorer, type gencode
Note: The leading and the trailing "/" will always be stripped (caused by
the filesystem database and ensured by the core).
Note: Double slashes ("//") will not be fixed and result in an error.
__object_name::
The full qualified name of the current object.
Available for: type manifest, type explorer, type gencode
__target_host::
The host we are deploying to.
Available for: explorer, initial manifest, type explorer, type manifest, type gencode
__type::
Path to the current type.
Available for: type manifest, type gencode
__type_explorer::
Directory that contains the type explorers.
Available for: type explorer
SEE ALSO
--------
- cdist(1)
COPYING
-------
Copyright \(C) 2011-2012 Nico Schottelius. Free use of this software is
granted under the terms of the GNU General Public License version 3 (GPLv3).
eof

124
docs/man/man1/cdist.text Normal file
View file

@ -0,0 +1,124 @@
cdist(1)
========
Nico Schottelius <nico-cdist--@--schottelius.org>
NAME
----
cdist - Configuration management
SYNOPSIS
--------
cdist [-h] [-V]
cdist banner
cdist config [-h] [-d] [-V] [-c CDIST_HOME] [-i MANIFEST] [-p] [-s] host [host ...]
DESCRIPTION
-----------
cdist is the frontend executable to the cdist configuration management.
cdist supports different as explained below. The options to the main
program are:
-h, --help::
Show the help screen
-V, --version::
Show version and exit
BANNER
-------
Displays the cdist banner.
CONFIG
------
Configure a system
-h, --help::
Show the help screen
-c CDIST_HOME, --cdist-home CDIST_HOME::
Instead of using the parent of the bin directory as cdist home,
use the specified directory
-d, --debug::
Enable debug output
-i MANIFEST, --initial-manifest MANIFEST::
Path to a cdist manifest or - to read from stdin
-p, --parallel::
Operate on multiple hosts in parallel
-s, --sequential::
Operate on multiple hosts sequentially
--remote-copy REMOTE_COPY:
Command to use for remote copy (should behave like scp)
--remote-exec REMOTE_EXEC:
Command to use for remote execution (should behave like ssh)
EXAMPLES
--------
--------------------------------------------------------------------------------
# Configure ikq05.ethz.ch with debug enabled
cdist config -d ikq05.ethz.ch
# Configure hosts in parallel and use a different home directory
cdist config -c ~/p/cdist-nutzung \
-p ikq02.ethz.ch ikq03.ethz.ch ikq04.ethz.ch
# Use custom remote exec / copy commands
cdist config --remote-exec /path/to/my/remote/exec \
--remote-copy /path/to/my/remote/copy \
-p ikq02.ethz.ch ikq03.ethz.ch ikq04.ethz.ch
# Display banner
cdist banner
# Show help
cdist --help
# Show Version
cdist --version
--------------------------------------------------------------------------------
ENVIRONMENT
-----------
TMPDIR, TEMP, TMP::
Setup the base directory for the temporary directory.
See http://docs.python.org/py3k/library/tempfile.html for
more information. This is rather useful, if the standard
directory used does not allow executables.
EXIT STATUS
-----------
The following exit values shall be returned:
0::
Successful completion
1::
One or more host configurations failed
SEE ALSO
--------
- cdist(7)
- cdist-reference(7)
COPYING
-------
Copyright \(C) 2011-2012 Nico Schottelius. Free use of this software is
granted under the terms of the GNU General Public License version 3 (GPLv3).

View file

@ -0,0 +1,199 @@
cdist-best-practice(7)
======================
Nico Schottelius <nico-cdist--@--schottelius.org>
NAME
----
cdist-best-practice - Practices used in real environments
PASSWORDLESS CONNECTIONS
------------------------
It is recommended to run cdist with public key authentication.
This requires a private/public key pair and the entry
"PermitRootLogin without-password" in the sshd server.
See sshd_config(5) and ssh-keygen(1).
SPEEDING UP SSH CONNECTIONS
---------------------------
When connecting to a new host, the initial delay with ssh connections
is pretty big. You can work around this by
"sharing of multiple sessions over a single network connection"
(quote from ssh_config(5)). The following code is suitable for
inclusion into your ~/.ssh/config:
--------------------------------------------------------------------------------
Host *
ControlPath ~/.ssh/master-%l-%r@%h:%p
ControlMaster auto
ControlPersist 10
--------------------------------------------------------------------------------
MULTI MASTER OR ENVIRONMENT SETUPS
----------------------------------
If you plan to distribute cdist among servers or use different
environments, you can do so easily with the included version
control git. For instance if you plan to use the typical three
environments production, integration and development, you can
realise this with git branches:
--------------------------------------------------------------------------------
# Go to cdist checkout
cd /path/to/cdist
# Create branches
git branch development
git branch integration
git branch production
# Make use of a branch, for instance production
git checkout production
--------------------------------------------------------------------------------
Similar if you want to have cdist checked out at multiple machines,
you can clone it multiple times:
--------------------------------------------------------------------------------
machine-a % git clone git://your-git-server/cdist
machine-b % git clone git://your-git-server/cdist
--------------------------------------------------------------------------------
SEPERATING WORK BY GROUPS
-------------------------
If you are working with different groups on one cdist-configuration,
you can delegate to other manifests and have the groups edit only
their manifests. You can use the following snippet in
**conf/manifests/init**:
--------------------------------------------------------------------------------
# Include other groups
sh -e "$__manifest/systems"
sh -e "$__manifest/cbrg"
--------------------------------------------------------------------------------
MAINTAINING MULTIPLE CONFIGURATIONS
-----------------------------------
When you need to manage multiple sites with cdist, like company_a, company_b
and private for instance, you can easily use git for this purpose.
Including a possible common base that is reused accross the different sites:
--------------------------------------------------------------------------------
# create branches
git branch company_a company_b common private
# make stuff for company a
git checkout company_a
# work, commit, etc.
# make stuff for company b
git checkout company_b
# work, commit, etc.
# make stuff relevant for all sites
git checkout common
# work, commit, etc.
# change to private and include latest common stuff
git checkout private
git merge common
--------------------------------------------------------------------------------
The following **.git/config** is taken from a a real world scenario:
--------------------------------------------------------------------------------
# Track upstream, merge from time to time
[remote "upstream"]
url = git://git.schottelius.org/cdist
fetch = +refs/heads/*:refs/remotes/upstream/*
# Same as upstream, but works when being offline
[remote "local"]
fetch = +refs/heads/*:refs/remotes/local/*
url = /home/users/nico/p/cdist
# Remote containing various ETH internal branches
[remote "eth"]
url = sans.ethz.ch:/home/services/sans/git/cdist-eth
fetch = +refs/heads/*:refs/remotes/eth/*
# Public remote that contains my private changes to cdist upstream
[remote "nico"]
url = git.schottelius.org:/home/services/git/cdist-nico
fetch = +refs/heads/*:refs/remotes/nico/*
# The "nico" branch will be synced with the remote nico, branch master
[branch "nico"]
remote = nico
merge = refs/heads/master
# ETH stable contains rock solid configurations used in various places
[branch "eth-stable"]
remote = eth
merge = refs/heads/stable
--------------------------------------------------------------------------------
Have a look at git-remote(1) to adjust the remote configuration, which allows
MULTIPLE DEVELOPERS WITH DIFFERENT TRUST
----------------------------------------
If you are working in an environment that requires different people to
work on the same configuration, but having different privileges, you can
implement this scenario with a gateway host and sudo:
- Create a dedicated user (for instance **cdist**)
- Setup the ssh-pubkey for this user that has the right to configure all hosts
- Create a wrapper to update the cdist configuration in ~cdist/cdist
- Allow every developer to execute this script via sudo as the user cdist
- Allow run of cdist as user cdist on specific hosts on a per user/group base
- f.i. nico ALL=(ALL) NOPASSWD: /home/cdist/bin/cdist config hostabc
For more details consult sudoers(5)
TEMPLATING
----------
* create directory templates/ in your type (convention)
* create the template as an executable file like templates/basic.conf.sh, it will output text using shell variables for the values
--------------------------------------------------------------------------------------
#!/bin/sh
# in the template, use cat << eof (here document) to output the text
# and use standard shell variables in the template
# output everything in the template script to stdout
cat << EOF
server {
listen 80;
server_name $SERVERNAME;
root $ROOT;
access_log /var/log/nginx/$SERVERNAME_access.log
error_log /var/log/nginx/$SERVERNAME_error.log
}
EOF
--------------------------------------------------------------------------------------
* in the manifest, export the relevant variables and add the following lines in your manifest:
--------------------------------------------------------------------------------------
# export variables needed for the template
export SERVERNAME='test"
export ROOT='/var/www/test'
# render the template
mkdir -p "$__object/files"
"$__type/templates/basic.conf.sh" > "$__object/files/basic.conf"
# send the rendered template
__file /etc/nginx/sites-available/test.conf --state present --source "$__object/files/basic.conf"
--------------------------------------------------------------------------------------
SEE ALSO
--------
- cdist(1)
- cdist-tutorial(7)
COPYING
-------
Copyright \(C) 2011-2012 Nico Schottelius. Free use of this software is
granted under the terms of the GNU General Public License version 3 (GPLv3).

View file

@ -0,0 +1,148 @@
cdist-bootstrap(7)
==================
Nico Schottelius <nico-cdist--@--schottelius.org>
NAME
----
cdist-bootstrap - setup cdist environment
INTRODUCTION
------------
This document describes the usual steps recommended for a new
cdist setup. It is recommended that you have read and understood
cdist-quickstart(7) before digging into this.
LOCATION
---------
First of all, you should think about where to store your configuration
database and who will be accessing or changing it. Secondly you have to
think about where to configure your hosts from, which may be a different
location.
For starters, having cdist (which includes the configuration database) on
your notebook should be fine.
Additionally an external copy of the git repository the configuration
relies in is recommended, for use as backup as well to allow easy collaboration
with others.
For more sophisticated setups developing cdist configurations with multiple
people, have a look at cdist-best-practice(7).
SETUP WORKING DIRECTORY AND BRANCH
----------------------------------
I assume you have a fresh copy of the cdist tree in ~/cdist, cloned from
one of the official urls (see cdist-quickstart(7) if you don't).
Entering the command "git branch" should show you "* master", which indicates
you are on the **master** branch.
The master branch reflects the latest development of cdist. As this is the
development branch, it may or may not work. There are also version branches
available, which are kept in a stable state. Let's use **git branch -r**
to list all branches:
--------------------------------------------------------------------------------
cdist% git branch -r
origin/1.0
origin/1.1
origin/1.2
origin/1.3
origin/1.4
origin/1.5
origin/1.6
origin/1.7
origin/2.0
origin/HEAD -> origin/master
origin/archive_shell_function_approach
origin/master
--------------------------------------------------------------------------------
So **2.0** is the latest version branch in this example.
All versions (2.0.x) within one version branch (2.0) are compatible to each
other and won't break your configuration when updating.
It's up to you decide on which branch you want to base your own work:
master contains more recent changes, newer types, but may also break.
The versions branches are stable, but thus may miss the latest features.
Your decision can be changed later on, but may result in merge conflicts,
which you'd have to solve.
Let's assume you want latest stuff and select the master branch as base for
your own work. Now it's time to create your branch, which contains your
local changes. I usually name it by the company/area I am working for:
ethz-systems, localch, customerX, ... But this is pretty much up to you.
In this tutorial I use the branch **mycompany**:
--------------------------------------------------------------------------------
cdist% git checkout -b mycompany origin/master
Branch mycompany set up to track remote branch master from origin.
Switched to a new branch 'mycompany'
cdist-user% git branch
master
* mycompany
--------------------------------------------------------------------------------
From now on, you can use git as usual to commit your changes in your own branch.
PUBLISHING THE CONFIGURATION
----------------------------
Usually a development machine like a notebook should be considered
temporary only. For this reason and to enable shareability, the configuration
should be published to another device as early as possible. The following
example shows how to publish the configuration to another host that is
reachable via ssh and has git installed:
--------------------------------------------------------------------------------
# Create bare git repository on the host named "loch"
cdist% ssh loch "GIT_DIR=/home/nutzer/cdist git init"
Initialized empty Git repository in /home/nutzer/cdist/
# Add remote git repo to git config
cdist% git remote add loch loch:/home/nutzer/cdist
# Configure the mycompany branch to push to loch
cdist% git config branch.mycompany.remote loch
# Configure mycompany branch to push into remote master branch
cdist% git config branch.mycompany.merge refs/heads/master
# Push mycompany branch to remote branch master initially
cdist% git push loch mycompany:refs/heads/master
--------------------------------------------------------------------------------
Now you have setup the git repository to synchronise the **mycompany**
branch with the **master** branch on the host **loch**. Thus you can commit
as usual in your branch and push out changes by entering ***git push***.
UPDATING FROM ORIGIN
--------------------
Whenever you want to update your cdist installation, you can use git to do so:
--------------------------------------------------------------------------------
# Update git repository with latest changes from origin
cdist% git fetch origin
# Update current branch with master branch from origin
cdist% git merge origin/master
# Alternative: Update current branch with 2.0 branch from origin
cdist% git merge origin/2.0
--------------------------------------------------------------------------------
SEE ALSO
--------
- cdist(1)
- cdist-tutorial(7)
COPYING
-------
Copyright \(C) 2012 Nico Schottelius. Free use of this software is
granted under the terms of the GNU General Public License version 3 (GPLv3).

View file

@ -0,0 +1,68 @@
cdist-explorer(7)
=================
Nico Schottelius <nico-cdist--@--schottelius.org>
NAME
----
cdist-explorer - Explore the target systems
DESCRIPTION
-----------
Explorer are small shell scripts, which will be executed on the target
host. The aim of the explorer is to give hints to types on how to act on the
target system. An explorer outputs the result to stdout, which is usually
a one liner, but may be empty or multi line especially in the case of
type explorers.
There are general explorers, which are run in an early stage, and
type explorers. Both work almost exactly the same way, with the difference
that the values of the general explorers are stored in a general location and
the type specific below the object.
Explorers can reuse other explorers on the target system by calling
$__explorer/<explorer_name> (general and type explorer) or
$__type_explorer/<explorer name> (type explorer).
In case of significant errors, the explorer may exit non-zero and return an
error message on stderr, which will cause cdist to abort.
You can also use stderr for debugging purposes while developing a new
explorer.
EXAMPLES
--------
A very simple explorer may look like this:
--------------------------------------------------------------------------------
hostname
--------------------------------------------------------------------------------
Which is in practise the ***hostname*** explorer.
A type explorer, which could check for the status of a package may look like this:
--------------------------------------------------------------------------------
if [ -f "$__object/parameter/name" ]; then
name="$(cat "$__object/parameter/name")"
else
name="$__object_id"
fi
# Except dpkg failing, if package is not known / installed
dpkg -s "$name" 2>/dev/null || exit 0
--------------------------------------------------------------------------------
SEE ALSO
--------
- cdist(1)
- cdist-reference(7)
- cdist-stages(7)
COPYING
-------
Copyright \(C) 2010-2012 Nico Schottelius. Free use of this software is
granted under the terms of the GNU General Public License version 3 (GPLv3).

View file

@ -0,0 +1,88 @@
cdist-hacker(7)
===============
Nico Schottelius <nico-cdist--@--schottelius.org>
NAME
----
cdist-hacker - How to get (stuff) into cdist
WELCOME
-------
Welcome dear hacker! I invite you to a tour of pointers to
get into the usable configuration mangament system, cdist.
The first thing to know is probably that cdist is brought to
you by people who care about how code looks like and who think
twice before merging or implementing a feature: Less features
with good usability are far better than the opposite.
REPORTING BUGS
--------------
If you believe you've found a bug and verified that it is
in the latest version, drop a mail to the cdist mailing list,
subject prefixed with "[BUG] " or create an issue on github.
CODING CONVENTIONS (EVERYWHERE)
-------------------------------
If something should be better done or needs to fixed, add the word FIXME
nearby, so grepping for FIXME gives all positions that need to be fixed.
Indention is 4 spaces (welcome to the python world).
HOW TO SUBMIT STUFF FOR INCLUSION INTO UPSTREAM CDIST
-----------------------------------------------------
If you did some cool changes to cdist, which you value as a benefit for
everybody using cdist, you're welcome to propose inclusion into upstream.
There are though some requirements to ensure your changes don't break others
work nor kill the authors brain:
- All files should contain the usual header (Author, Copying, etc.)
- Code submission must be done via git
- Do not add conf/manifest/init - This file should only be touched in your
private branch!
- Code to be included should be branched of the upstream "master" branch
- Exception: Bugfixes to a version branch
- On a merge request, always name the branch I should pull from
- Always ensure **all** manpages build. Use **./build man** to test.
- If you developed more than **one** feature, consider submitting them in
seperate branches. This way one feature can already be included, even if
the other needs to be improved.
As soon as your work meets these requirements, write a mail
for inclusion to the mailinglist **cdist at cdist -- at -- l.schottelius.org**
or open a pull request at http://github.com/telmich/cdist.
HOW TO SUBMIT A NEW TYPE
------------------------
For detailled information about types, see cdist-type(7).
Submitting a type works as described above, with the additional requirement
that a corresponding manpage named man.text in asciidoc format with
the manpage-name "cdist-type__NAME" is included in the type directory
AND asciidoc is able to compile it (i.e. do NOT have to many "=" in the second
line).
Warning: Submitting "exec" or "run" types that simply echo their parameter in
gencode* will not be accepted, because they are of no use. Every type can output
code and thus such a type introduces redundant functionality that is given by
core cdist already.
SEE ALSO
--------
- cdist(7)
COPYING
-------
Copyright \(C) 2011-2012 Nico Schottelius. Free use of this software is
granted under the terms of the GNU General Public License version 3 (GPLv3).

View file

@ -0,0 +1,164 @@
cdist-manifest(7)
=================
Nico Schottelius <nico-cdist--@--schottelius.org>
NAME
----
cdist-manifest - (Re-)Use types
DESCRIPTION
-----------
Manifests are used to define which objects to create.
Objects are instances of **types**, like in object orientated programming languages.
An object is represented by the combination of
**type + slash + object name**: **__file/etc/cdist-configured** is an
object of the type ***__file*** with the name ***etc/cdist-configured***.
All available types can be found in the **conf/type/** directory,
use **ls conf/type** to get the list of available types. If you have
setup the MANPATH correctly, you can use **man cdist-reference** to access
the reference with pointers to the manpages.
Types in manifests are used like normal command line tools. Let's have a look
at an example:
--------------------------------------------------------------------------------
# Create object of type __package with the parameter state = removed
__package apache2 --state removed
# Same with the __directory type
__directory /tmp/cdist --state present
--------------------------------------------------------------------------------
These two lines create objects, which will later be used to realise the
configuration on the target host.
Manifests are executed locally as a shell script using **/bin/sh -e**.
The resulting objects are stored in an internal database.
The same object can be redefined in multiple different manifests as long as
the parameters are exactly the same.
In general, manifests are used to define which types are used depending
on given conditions.
INITIAL AND TYPE MANIFESTS
--------------------------
Cdist knows about two types of manifests: The initial manifest and type
manifests. The initial manifest is used to define, which configurations
to apply to which hosts. The type manifests are used to create objects
from types. More about manifests in types can be found in cdist-type(7).
DEFINE STATE IN THE INITIAL MANIFEST
------------------------------------
The **initial manifest** is the entry point for cdist to find out, which
**objects** to configure on the selected host.
Cdist searches for the initial manifest at **conf/manifest/init**.
Within this initial manifest, you define, which objects should be
created on which host. To distinguish between hosts, you can use the
environment variable **__target_host**. Let's have a look at a simple
example:
--------------------------------------------------------------------------------
__cdistmarker
case "$__target_host" in
localhost)
__directory /home/services/kvm-vm --parents yes
;;
esac
--------------------------------------------------------------------------------
This manifest says: Independent of the host, always use the type
***__cdistmarker***, which creates the file **/etc/cdist-configured**,
with the timestamp as content.
The directory ***/home/services/kvm-vm***, including all parent directories,
is only created on the host ***localhost***.
As you can see, there is no magic involved, the manifest is simple shell code that
utilises cdist types. Every available type can be executed like a normal
command.
SPLITTING UP THE INITIAL MANIFEST
---------------------------------
If you want to split up your initial manifest, you can create other shell
scripts in **conf/manifest/** and include them in **conf/manifest/init**.
Cdist provides the environment variable ***__manifest*** to reference to
the directory containing the initial manifest (see cdist-reference(7)).
The following example would include every file with a **.sh** suffix:
--------------------------------------------------------------------------------
# Include *.sh
for manifest in $__manifest/*.sh; do
# And source scripts into our shell environment
. "$manifest"
done
--------------------------------------------------------------------------------
DEPENDENCIES
------------
If you want to describe that something requires something else, just
setup the variable "require" to contain the requirements. Multiple
requirements can be added white space seperated.
--------------------------------------------------------------------------------
# No dependency
__file /etc/cdist-configured
# Require above object
require="__file/etc/cdist-configured" __link /tmp/cdist-testfile \
--source /etc/cdist-configured --type symbolic
# Require two objects
require="__file/etc/cdist-configured __link/tmp/cdist-testfile" \
__file /tmp/cdist-another-testfile
--------------------------------------------------------------------------------
All objects that are created in a type manifest are automatically required
from the type that is calling them. This is called "autorequirement" in
cdist jargon.
EXAMPLES
--------
The initial manifest may for instance contain the following code:
--------------------------------------------------------------------------------
# Always create this file, so other sysadmins know cdist is used.
__file /etc/cdist-configured --type file
case "$__target_host" in
my.server.name)
__file /root/bin/ --type directory
__file /etc/issue.net --type file --source "$__manifest/issue.net
;;
esac
--------------------------------------------------------------------------------
The manifest of the type "nologin" may look like this:
--------------------------------------------------------------------------------
__file /etc/nologin --type file --source "$__type/files/default.nologin"
--------------------------------------------------------------------------------
SEE ALSO
--------
- cdist-tutorial(7)
- cdist-type(7)
COPYING
-------
Copyright \(C) 2010-2012 Nico Schottelius. Free use of this software is
granted under the terms of the GNU General Public License version 3 (GPLv3).

View file

@ -0,0 +1,103 @@
cdist-quickstart(7)
===================
Nico Schottelius <nico-cdist--@--schottelius.org>
NAME
----
cdist-quickstart - jump in and enjoy cdist
INTRODUCTION
------------
This tutorial is aimed at people learning cdist and shows
typical approaches as well as gives an easy start into
the world of configuration management.
This tutorial assumes you are configuring **localhost**, because
it is always available. Just replace **localhost** with your target
host for real life usage.
QUICK START - GET YOUR HANDS DIRTY NOW
--------------------------------------
For those who just want to configure a system with the
cdist configuration management and do not need (or want)
to understand everything.
Cdist uses **ssh** for communication and transportation
and usually logs into the **target host** as the
**root** user. So you need to configure the **ssh server**
of the target host to allow root logins: Edit
the file **/etc/ssh/sshd_config** and add one of the following
lines:
--------------------------------------------------------------------------------
# Allow login only via public key
PermitRootLogin without-password
# Allow login via password and public key
PermitRootLogin yes
--------------------------------------------------------------------------------
As cdist uses ssh intensively, it is recommended to setup authentication
with public keys:
--------------------------------------------------------------------------------
# Generate pubkey pair as a normal user
ssh-keygen
# Copy pubkey over to target host
ssh-copy-id root@localhost
--------------------------------------------------------------------------------
Have a look at ssh-agent(1) and ssh-add(1) on how to cache the password for
your public key. Usually it looks like this:
--------------------------------------------------------------------------------
# Start agent and export variables
eval `ssh-agent`
# Add keys (requires password for every identity file)
ssh-add
--------------------------------------------------------------------------------
At this point you should be able to ***ssh root@localhost*** without
re-entering the password. If something failed until here, ensure that
all steps went successfully and you have read and understood the
documentation.
As soon as you are able to login without password to localhost,
we can use cdist to configure it. You can copy and paste the following
code into your shell to get started and configure localhost:
--------------------------------------------------------------------------------
# Get cdist
git clone git://git.schottelius.org/cdist
# Create manifest (maps configuration to host(s)
cd cdist
echo '__file /etc/cdist-configured' > conf/manifest/init
# Configure localhost in verbose mode
./bin/cdist config -v localhost
# Find out that cdist created /etc/cdist-configured
ls -l /etc/cdist-configured
--------------------------------------------------------------------------------
That's it, you've successfully used cdist to configure your first host!
Continue reading the next sections, to understand what you did and how
to create a more sophisticated configuration.
SEE ALSO
--------
- cdist(1)
- cdist-tutorial(7)
COPYING
-------
Copyright \(C) 2011-2012 Nico Schottelius. Free use of this software is
granted under the terms of the GNU General Public License version 3 (GPLv3).

View file

@ -0,0 +1,46 @@
cdist-remote-exec-copy(7)
=========================
Nico Schottelius <nico-cdist--@--schottelius.org>
NAME
----
cdist-remote-exec-copy - How to use remote exec and copy
INTRO
-----
Cdist interacts with the target host in two ways:
- it executes code (__remote_exec)
- and it copies files (__remote_copy)
By default this is accomplished with ssh and scp respectively.
The default implementations used by cdist are:
__remote_exec: ssh -o User=root -q
__remote_copy: scp -o User=root -q
The user can override these defaults by providing custom implementations and
passing them to cdist with the --remote-exec and/or --remote-copy arguments.
For __remote_exec, the custom implementation must behave as if it where ssh.
For __remote_copy, it must behave like scp.
With this simple interface the user can take total control of how cdist
interacts with the target when required, while the default implementation
remains as simple as possible.
EXAMPLES
--------------
See cdist/other/examples/remote/ for some example implementations.
SEE ALSO
--------
- cdist(7)
COPYING
-------
Copyright \(C) 2011-2012 Nico Schottelius. Free use of this software is
granted under the terms of the GNU General Public License version 3 (GPLv3).

View file

@ -0,0 +1,89 @@
cdist-stages(7)
===============
Nico Schottelius <nico-cdist--@--schottelius.org>
NAME
----
cdist-stages - Stages used during configuration deployment
DESCRIPTION
-----------
Starting the execution of deployment with cdist, cdist passes
through different stages.
STAGE 1: TARGET INFORMATION RETRIEVAL
-------------------------------------
In this stage information is collected about the target host using so called
explorers. Every existing explorer is run on the target and the output of all
explorers are copied back into the local cache. The results can be used by
manifests and types.
STAGE 2: RUN THE INITIAL MANIFEST
---------------------------------
The initial manifest, which should be used for mappings of hosts to types,
is executed. This stage creates objects in a cconfig database that contains
the objects as defined in the manifest for the specific host. In this stage,
no conflicts may occur, i.e. no object of the same type with the same id may
be created, if it has different parameters.
STAGE 3: OBJECT INFORMATION RETRIEVAL
-------------------------------------
Every object is checked whether its type has explorers and if so, these are
executed on the target host. The results are transfered back
and can be used in the following stages to decide what changes need to be made
on the target to implement the desired state.
STAGE 4: RUN THE OBJECT MANIFEST
--------------------------------
Every object is checked whether its type has a executable manifest. The
manifest script may generate and change the created objects. In other words,
one type can reuse other types.
For instance the object __apache/www.example.org is of type __apache, which may
contain a manifest script, which creates new objects of type __file.
The newly created objects are merged back into the existing tree. No conflicts
may occur during the merge. A conflict would mean that two different objects
try to create the same object, which indicates a broken configuration.
STAGE 5: CODE GENERATION
------------------------
In this stage for every created object its type is checked for executable
gencode scripts. The gencode scripts generate the code to be executed on the
target on stdout. If the gencode executables fail, they must print diagnostic
messages on stderr and exit non-zero.
STAGE 6: CODE EXECUTION
-----------------------
For every object the resulting code from the previous stage is transferred to
the target host and executed there to apply the configuration changes.
STAGE 7: CACHE
--------------
The cache stores the information from the current run for later use.
SUMMARY
-------
If, and only if, all the stages complete without an errors, the configuration
will be applied to the target.
SEE ALSO
--------
- cdist(1)
- cdist-reference(7)
COPYING
-------
Copyright \(C) 2010-2012 Nico Schottelius, Steven Armstrong. Free use of this software is
granted under the terms of the GNU General Public License version 3 (GPLv3).

View file

@ -0,0 +1,58 @@
cdist-tutorial(7)
=================
Nico Schottelius <nico-cdist--@--schottelius.org>
NAME
----
cdist-tutorial - a guided introduction into cdist
INTRODUCTION
------------
This document gives you a pointer on what to read in
which order and is thus a "guide to the right locations".
So in case you are just starting, just "begin at the beginning"
(Brave New World). You can see the target audience in [] brackets
after the description.
cdist-quickstart::
New to cdist? Want to get your hands dirty? Read this. [beginner]
cdist-bootstrap::
The comprehensive guide to your first cdist installation [beginner]
cdist-manifest::
Learn how to define which hosts get which configurations [beginner]
cdist-type::
Understand how types are working and created [intermediate]
cdist-best-practice::
Hints from real life experience to help you to organise cdist [intermediate]
cdist-reference::
The type, explorers and environment variables reference [intermediate]
cdist-explorer::
Interested in getting more information about the target system? [intermediate]
cdist-stages::
Understand the internal workflow of cdist. [advanced]
cdist-hacker::
README, if you want to extend or modify cdist. [hacker]
SEE ALSO
--------
- cdist(1)
- cdist-type(7)
- cdist-best-practice(7)
- cdist-stages(7)
- Brave New World by Aldous Huxley
COPYING
-------
Copyright \(C) 2011-2012 Nico Schottelius. Free use of this software is
granted under the terms of the GNU General Public License version 3 (GPLv3).

View file

@ -0,0 +1,279 @@
cdist-type(7)
=============
Nico Schottelius <nico-cdist--@--schottelius.org>
NAME
----
cdist-type - Functionality bundled
SYNOPSIS
--------
__TYPE ID --parameter value [--parameter value ...]
__TYPE --parameter value [--parameter value ...] (for singletons)
DESCRIPTION
-----------
Types are the main component of cdist and define functionality. If you
use cdist, you'll write a type for every functionality you would like
to use.
HOW TO USE A TYPE
-----------------
You can use types from the initial manifest or the type manifest like a
normal command:
--------------------------------------------------------------------------------
# Creates empty file /etc/cdist-configured
__file /etc/cdist-configured --type file
# Ensure tree is installed
__package tree --state installed
--------------------------------------------------------------------------------
A list of supported types can be found in the cdist-reference(7) manpage.
SINGLETON TYPES
---------------
If a type is flagged as a singleton, it may be used only
once per host. This is useful for types which can be used only once on a
system. Singleton types do not take an object name as argument.
Example:
--------------------------------------------------------------------------------
# __issue type manages /etc/issue
__issue
# Probably your own type - singletons may use parameters
__myfancysingleton --colour green
--------------------------------------------------------------------------------
HOW TO WRITE A NEW TYPE
-----------------------
A type consists of
- parameter (optional)
- manifest (optional)
- singleton (optional)
- explorer (optional)
- gencode (optional)
Types are stored below conf/type/. Their name should always be prefixed with
two underscores (__) to prevent collisions with other executables in $PATH.
To begin a new type, just create the directory **conf/type/__NAME**.
DEFINING PARAMETERS
-------------------
Every type consists of required, optional and boolean parameters, which must
be created in a newline seperated file in ***parameter/required***,
***parameter/required_multiple***, ***parameter/optional***,
***parameter/optional_multiple*** and ***parameter/boolean***.
Parameters which are allowed multiple times should be listed in
required_multiple or optional_multiple respectively. For all other parameters
the standard unix behaviour of the last given wins is applied.
If either is missing, the type will have no required, no optional, no boolean
or no parameters at all.
Example:
--------------------------------------------------------------------------------
echo servername >> conf/type/__nginx_vhost/parameter/required
echo logdirectory >> conf/type/__nginx_vhost/parameter/optional
echo server_alias >> conf/type/__nginx_vhost/parameter/optional_multiple
echo use_ssl >> conf/type/__nginx_vhost/parameter/boolean
--------------------------------------------------------------------------------
USING PARAMETERS
----------------
The parameters given to a type can be accessed and used in all type scripts
(e.g manifest, gencode-*, explorer/*). Note that boolean parameters are
represented by file existence. File exists -> True,
file does not exist -> False
Example: (e.g. in conf/type/__nginx_vhost/manifest)
--------------------------------------------------------------------------------
# required parameter
servername="$(cat "$__object/parameter/servername")"
# optional parameter
if [ -f "$__object/parameter/logdirectory" ]; then
logdirectory="$(cat "$__object/parameter/logdirectory")"
fi
# boolean parameter
if [ -f "$__object/parameter/use_ssl" ]; then
# file exists -> True
# do some fancy ssl stuff
fi
# parameter with multiple values
if [ -f "$__object/parameter/server_alias" ]; then
for alias in $(cat "$__object/parameter/server_alias"); do
echo $alias > /some/where/usefull
done
fi
--------------------------------------------------------------------------------
INPUT FROM STDIN
-----------------
Every type can access what has been written on stdin when it has been called.
The result is saved into the ***stdin*** file in the object directory.
Example use of a type: (e.g. in conf/type/__archlinux_hostname)
--------------------------------------------------------------------------------
__file /etc/rc.conf --source - << eof
...
HOSTNAME="$__target_host"
...
eof
--------------------------------------------------------------------------------
If you have not seen this syntax (<< eof) before, it may help you to read
about "here documents".
In the __file type, stdin is used as source for the file, if - is used for source:
--------------------------------------------------------------------------------
if [ -f "$__object/parameter/source" ]; then
source="$(cat "$__object/parameter/source")"
if [ "$source" = "-" ]; then
source="$__object/stdin"
fi
....
--------------------------------------------------------------------------------
WRITING THE MANIFEST
--------------------
In the manifest of a type you can use other types, so your type extends
their functionality. A good example is the __package type, which in
a shortened version looks like this:
--------------------------------------------------------------------------------
os="$(cat "$__global/explorer/os")"
case "$os" in
archlinux) type="pacman" ;;
debian|ubuntu) type="apt" ;;
gentoo) type="emerge" ;;
*)
echo "Don't know how to manage packages on: $os" >&2
exit 1
;;
esac
__package_$type "$@"
--------------------------------------------------------------------------------
As you can see, the type can reference different environment variables,
which are documented in cdist-reference(7).
Always ensure the manifest is executable, otherwise cdist will not be able
to execute it. For more information about manifests see cdist-manifest(7).
SINGLETON - ONE INSTANCE ONLY
-----------------------------
If you want to ensure that a type can only be used once per target, you can
mark it as a singleton: Just create the (empty) file "singleton" in your type
directory:
--------------------------------------------------------------------------------
touch conf/type/__NAME/singleton
--------------------------------------------------------------------------------
This will also change the way your type must be called:
--------------------------------------------------------------------------------
__YOURTYPE --parameter value
--------------------------------------------------------------------------------
As you can see, the object ID is omitted, because it does not make any sense,
if your type can be used only once.
THE TYPE EXPLORERS
------------------
If a type needs to explore specific details, it can provide type specific
explorers, which will be executed on the target for every created object.
The explorers are stored under the "explorer" directory below the type.
It could for instance contain code to check the md5sum of a file on the
client, like this (shortened version from the type __file):
--------------------------------------------------------------------------------
if [ -f "$__object/parameter/destination" ]; then
destination="$(cat "$__object/parameter/destination")"
else
destination="/$__object_id"
fi
if [ -e "$destination" ]; then
md5sum < "$destination"
fi
--------------------------------------------------------------------------------
WRITING THE GENCODE SCRIPT
--------------------------
There are two gencode scripts: ***gencode-local*** and ***gencode-remote***.
The output of gencode-local is executed locally, whereas
the output of gencode-remote is executed on the target.
The gencode scripts can make use of the parameters, the global explorers
and the type specific explorers.
If the gencode scripts encounter an error, it should print diagnostic
messages to stderr and exit non-zero. If you need to debug the gencode
script, you can write to stderr:
--------------------------------------------------------------------------------
# Debug output to stderr
echo "My fancy debug line" >&2
# Output to be saved by cdist for execution on the target
echo "touch /etc/cdist-configured"
--------------------------------------------------------------------------------
HINTS FOR TYPEWRITERS
----------------------
It must be assumed that the target is pretty dumb and thus does not have high
level tools like ruby installed. If a type requires specific tools to be present
on the target, there must be another type that provides this tool and the first
type should create an object of the specific type.
If your type wants to save temporary data, that may be used by other types
later on (for instance __file), you can save them in the subdirectory
"files" below $__object (but you must create it yourself).
cdist will not touch this directory.
If your type contains static files, it's also recommended to place them in
a folder named "files" within the type (again, because cdist guarantees to
never ever touch this folder).
HOW TO INCLUDE A TYPE INTO UPSTREAM CDIST
-----------------------------------------
If you think your type may be useful for others, ensure it works with the
current master branch of cdist and have a look at cdist-hacker(7) on
how to submit it.
SEE ALSO
--------
- cdist-explorer(7)
- cdist-hacker(7)
- cdist-stages(7)
- cdist-tutorial(7)
COPYING
-------
Copyright \(C) 2011-2012 Nico Schottelius. Free use of this software is
granted under the terms of the GNU General Public License version 3 (GPLv3).