Merge branch 'master' into type__jail_boolean

This commit is contained in:
Nico Schottelius 2012-11-27 08:58:14 +01:00
commit fd8fdf8b54
12 changed files with 101 additions and 42 deletions

7
build
View file

@ -331,14 +331,17 @@ eof
done
;;
web)
set -e
web-doc)
rsync -av "${basedir}/docs/web/" "${WEBTOPDIR}"
cd "${WEBDIR}" && git add "${WEBBASE}"
cd "${WEBDIR}" && git commit -m "cdist update" "${WEBBASE}" "${WEBPAGE}"
cd "${WEBDIR}" && make pub
;;
web)
set -e
$0 web-doc
# Fix ikiwiki, which does not like symlinks for pseudo security
ssh tee.schottelius.org \
"cd /home/services/www/nico/www.nico.schottelius.org/www/software/cdist/man &&

View file

@ -3,7 +3,7 @@
# not existing and state != absent
#
state="present"
[ -f "$__object/parameter/state" ] state="$(cat "$__object/parameter/state")"
[ -f "$__object/parameter/state" ] && state="$(cat "$__object/parameter/state")"
[ "$state" = "absent" ] && exit 0
exists="$(cat "$__object/explorer/exists")"

View file

@ -186,8 +186,6 @@ class CdistObject(object):
return os.path.join(self.path, "explorer")
requirements = fsproperty.FileListProperty(lambda obj: os.path.join(obj.absolute_path, 'require'))
before = fsproperty.FileListProperty(lambda obj: os.path.join(obj.absolute_path, 'before'))
after = fsproperty.FileListProperty(lambda obj: os.path.join(obj.absolute_path, 'after'))
autorequire = fsproperty.FileListProperty(lambda obj: os.path.join(obj.absolute_path, 'autorequire'))
parameters = fsproperty.DirectoryDictProperty(lambda obj: os.path.join(obj.base_path, obj.parameter_path))
explorers = fsproperty.DirectoryDictProperty(lambda obj: os.path.join(obj.base_path, obj.explorer_path))

View file

@ -23,7 +23,6 @@
import argparse
import logging
import os
import warnings
import sys
import cdist
@ -93,12 +92,8 @@ class Emulator(object):
def commandline(self):
"""Parse command line"""
self.meta_parameters = dict.fromkeys(('after', 'before'))
meta_parser = argparse.ArgumentParser(add_help=False)
for meta_parameter in self.meta_parameters.keys():
meta_parser.add_argument('--%s' % meta_parameter, action='append', required=False)
parser = argparse.ArgumentParser(add_help=False, parents=[meta_parser], argument_default=argparse.SUPPRESS)
parser = argparse.ArgumentParser(add_help=False, argument_default=argparse.SUPPRESS)
for parameter in self.cdist_type.required_parameters:
argument = "--" + parameter
@ -124,11 +119,6 @@ class Emulator(object):
self.args = parser.parse_args(self.argv[1:])
self.log.debug('Args: %s' % self.args)
# Handle meta parameters
for meta_parameter in self.meta_parameters.keys():
if meta_parameter in self.args:
self.meta_parameters[meta_parameter] = getattr(self.args, meta_parameter)
delattr(self.args, meta_parameter)
def setup_object(self):
# Setup object_id - FIXME: unset / do not setup anymore!
@ -185,18 +175,10 @@ class Emulator(object):
def record_requirements(self):
"""record requirements"""
for key in ('before', 'after'):
if key in self.meta_parameters and self.meta_parameters[key]:
for value in self.meta_parameters[key]:
self.log.debug("Recording requirement: %s %s %s", self.cdist_object.name, key, value)
dependency_list = getattr(self.cdist_object, key)
# append to the object.after or object.before lists
dependency_list.append(value)
if "require" in self.env:
warnings.warn("The 'require' envrionment variable is deprecated. Use the --before and --after meta parameters to define dependencies.", category=PendingDeprecationWarning, stacklevel=2)
requirements = self.env['require']
self.log.debug("reqs = " + requirements)
for requirement in requirements.split(" "):
# Ignore empty fields - probably the only field anyway
if len(requirement) == 0: continue
@ -205,10 +187,11 @@ class Emulator(object):
cdist_object = self.cdist_object.object_from_name(requirement)
self.log.debug("Recording requirement: " + requirement)
# Save the sanitised version, not the user supplied one
# (__file//bar => __file/bar)
# This ensures pattern matching is done against sanitised list
self.cdist_object.after.append(cdist_object.name)
self.cdist_object.requirements.append(cdist_object.name)
def record_auto_requirements(self):
"""An object shall automatically depend on all objects that it defined in it's type manifest.

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
#
# 2011-2012 Steven Armstrong (steven-cdist at armstrong.cc)
# 2011 Steven Armstrong (steven-cdist at armstrong.cc)
#
# This file is part of cdist.
#
@ -77,6 +77,7 @@ class DependencyResolver(object):
lists of all dependencies including the key object itself.
"""
if self._dependencies is None:
log.info("Resolving dependencies...")
self._dependencies = d = {}
self._preprocess_requirements()
for name,cdist_object in self.objects.items():
@ -109,21 +110,10 @@ class DependencyResolver(object):
raise RequirementNotFoundError(pattern)
def _preprocess_requirements(self):
"""Find all before, after and autorequire dependencies and merge them
to be just requirements for further processing.
"""Find all autorequire dependencies and merge them to be just requirements
for further processing.
"""
for cdist_object in self.objects.values():
if cdist_object.after:
cdist_object.requirements.extend(cdist_object.after)
# As we changed the object on disc, we have to ensure it is not
# preprocessed again if someone would call us multiple times.
cdist_object.after = []
if cdist_object.before:
for other_object in self.find_requirements_by_name(cdist_object.before):
other_object.requirements.append(cdist_object.name)
# As we changed the object on disc, we have to ensure it is not
# preprocessed again if someone would call us multiple times.
cdist_object.before = []
if cdist_object.autorequire:
# The objects (children) that this cdist_object (parent) defined
# in it's type manifest shall inherit all explicit requirements

View file

@ -87,7 +87,6 @@ class ObjectTestCase(test.CdistTestCase):
self.cdist_object.code_local = ''
self.cdist_object.code_remote = ''
self.cdist_object.state = ''
self.cdist_object.requirements = []
def test_name(self):
self.assertEqual(self.cdist_object.name, '__third/moon')

View file

@ -10,7 +10,6 @@ next:
* New Type: __user_groups (Steven Armstrong)
* Type __user: Remove --groups support (now provided by __user_groups)
* Type __apt_ppa: Bugfix: Installeded ppa detection (Steven Armstrong)
* Core: Support for --after and --before parameters
2.1.0pre8: 2012-11-15
* Type cleanup: __apt_ppa, __apt_ppa_update_index, __file,

View file

@ -0,0 +1,3 @@
Use roundup for testing included types?
http://bmizerany.github.com/roundup/

View file

@ -0,0 +1,6 @@
Target version proposed date features
2.1. 2012-12-01 initial support for before/after requirements
2.2. 2013-03-01 initial notifications support,
replace require="" with before/after
2.3. 2013-06-01 installation support: pre-os and install types
2.4. 2013-09-01 performance speedup via parallelisation

View file

@ -30,6 +30,15 @@ Host *
ControlPersist 10
--------------------------------------------------------------------------------
SPEEDING UP SHELL EXECUTION
----------------------------
On the source host, ensure that /bin/sh is *not* bash: bash is quite slow for
script execution. Instead, you could use dash after installing it:
--------------------------------------------------------------------------------
ln -sf /bin/dash /bin/sh
--------------------------------------------------------------------------------
MULTI MASTER OR ENVIRONMENT SETUPS
----------------------------------

View file

@ -11,6 +11,7 @@ cdist is an alternative to other configuration management systems like
[cfengine](http://www.cfengine.org/)
and [puppet](http://www.puppetlabs.com/).
* [[Why should I use cdist?|why]]
* [[Documentation|documentation]]
* [[Supported Operating Systems|os]]
* [[Installation|install]]

68
docs/web/cdist/why.mdwn Normal file
View file

@ -0,0 +1,68 @@
[[!meta title="Why should I use cdist?"]]
[[!toc]]
There are several motivations to use cdist, these
are probably the most popular ones.
## Known language
Cdist is being configured in
[shell script](https://en.wikipedia.org/wiki/Shell_script).
Shell script is used by UNIX system engineers for decades.
So when cdist is introduced, your staff does not need to learn a new
[DSL](https://en.wikipedia.org/wiki/Domain-specific_language)
or programming language.
## Powerful language
Not only is shell scripting widely known by system engineers,
but it is also a very powerful language. Here are some features
which make daily work easy:
* Configuration can react dynamicly on explored values
* High level string manipulation (using sed, awk, grep)
* Conditional support (**if, case**)
* Loop support (**for, while**)
* Support for dependencies between cdist types
## More than shell scripting
If you compare regular shell scripting with cdist, there is one major
difference: When using cdist types,
the results are
[idempotent](https://en.wikipedia.org/wiki/Idempotence).
In practise that means it does not matter in which order you
call cdist types, the result is always the same.
## Zero dependency configuration management
Cdist requires very litte on a target system. Even better,
in almost all cases all dependencies are usually fulfilled.
Cdist does not require an agent or a high level programming
languages on the target host: it will run on any host that
has an **ssh server running** and a posix compatible shell
(**/bin/sh**).
## Push based distribution
Cdist uses the push based model for configuration. In this
scenario, one (or more) computers connect the target hosts
and apply the configuration. That way the source host has
very little requirements: Cdist can even run on a sysadmin
notebook that is loosely connected to the network and has
limited amount of resources.
Furthermore, from a security point of view, only one machine
needs access to the target hosts. No target hosts will ever
need to connect back to the source host, which contains the
full configuration.
## Highly scalable
If at some point you manage more hosts than can be handled from
a single source host, you can simply add more resources: Either
add more cores to one host or add hosts.
Cdist will utilise the given resources in parallel.
[[!tag cdist unix]]