diff --git a/build b/build index fb01c565..6fe8960f 100755 --- a/build +++ b/build @@ -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 && diff --git a/cdist/conf/type/__qemu_img/gencode-remote b/cdist/conf/type/__qemu_img/gencode-remote index e5ff1b4f..2a76cf8f 100644 --- a/cdist/conf/type/__qemu_img/gencode-remote +++ b/cdist/conf/type/__qemu_img/gencode-remote @@ -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")" diff --git a/cdist/core/cdist_object.py b/cdist/core/cdist_object.py index 7e587bf3..90a21e59 100644 --- a/cdist/core/cdist_object.py +++ b/cdist/core/cdist_object.py @@ -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)) diff --git a/cdist/emulator.py b/cdist/emulator.py index bd3661d3..a9c760cb 100644 --- a/cdist/emulator.py +++ b/cdist/emulator.py @@ -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. diff --git a/cdist/resolver.py b/cdist/resolver.py index d181d066..c1b2c292 100644 --- a/cdist/resolver.py +++ b/cdist/resolver.py @@ -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 diff --git a/cdist/test/object/__init__.py b/cdist/test/object/__init__.py index 7bdc037e..3a91f709 100644 --- a/cdist/test/object/__init__.py +++ b/cdist/test/object/__init__.py @@ -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') diff --git a/docs/changelog b/docs/changelog index 943d83e4..798a5b00 100644 --- a/docs/changelog +++ b/docs/changelog @@ -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, diff --git a/docs/dev/logs/2012-11-21.idea-shell-testing b/docs/dev/logs/2012-11-21.idea-shell-testing new file mode 100644 index 00000000..2a657053 --- /dev/null +++ b/docs/dev/logs/2012-11-21.idea-shell-testing @@ -0,0 +1,3 @@ +Use roundup for testing included types? + + http://bmizerany.github.com/roundup/ diff --git a/docs/dev/logs/2012-11-21.roadmap-proposal b/docs/dev/logs/2012-11-21.roadmap-proposal new file mode 100644 index 00000000..cd60ffe6 --- /dev/null +++ b/docs/dev/logs/2012-11-21.roadmap-proposal @@ -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 diff --git a/docs/man/man7/cdist-best-practice.text b/docs/man/man7/cdist-best-practice.text index a8851f7f..818c423a 100644 --- a/docs/man/man7/cdist-best-practice.text +++ b/docs/man/man7/cdist-best-practice.text @@ -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 ---------------------------------- diff --git a/docs/web/cdist.mdwn b/docs/web/cdist.mdwn index ee24e910..74457fc8 100644 --- a/docs/web/cdist.mdwn +++ b/docs/web/cdist.mdwn @@ -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]] diff --git a/docs/web/cdist/why.mdwn b/docs/web/cdist/why.mdwn new file mode 100644 index 00000000..0fcdf5c5 --- /dev/null +++ b/docs/web/cdist/why.mdwn @@ -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]]