Merge remote-tracking branch 'telmich/master' into nfs

This commit is contained in:
Steven Armstrong 2012-01-06 11:04:17 +01:00
commit a511461d9b
47 changed files with 615 additions and 197 deletions

6
README
View file

@ -53,8 +53,6 @@ UNIX, simplicity, familar environment | cdist is configured in POSIX shell
The cdist documentation is included as manpages in the distribution. The cdist documentation is included as manpages in the distribution.
* You can [browse the documentation of the latest version online](man) as well. * You can [browse the documentation of the latest version online](man) as well.
* Or you can watch the youtube **video**
[cdist installation and first usage in less than 60 seconds][http://www.youtube.com/watch?v=PRMjzy48eTI).
* Have a look at the [given speeches](speeches) * Have a look at the [given speeches](speeches)
### OS support ### OS support
@ -133,7 +131,7 @@ To install cdist, execute the following commands:
export PATH=$PATH:$(pwd -P)/bin export PATH=$PATH:$(pwd -P)/bin
# If you want the manpages # If you want the manpages
./build.sh man ./build man
export MANPATH=$MANPATH:$(pwd -P)/doc/man export MANPATH=$MANPATH:$(pwd -P)/doc/man
@ -180,7 +178,7 @@ To upgrade cdist in the current branch use
git pull git pull
# Also update the manpages # Also update the manpages
./build.sh man ./build man
export MANPATH=$MANPATH:$(pwd -P)/doc/man export MANPATH=$MANPATH:$(pwd -P)/doc/man
If you stay on a version branche (i.e. 1.0, 1.1., ...), nothing should break. If you stay on a version branche (i.e. 1.0, 1.1., ...), nothing should break.

22
build
View file

@ -26,13 +26,16 @@
# exit on any error # exit on any error
#set -e #set -e
version=$(git describe)
# Manpage and HTML # Manpage and HTML
A2XM="a2x -f manpage --no-xmllint -a encoding=UTF-8" A2XM="a2x -f manpage --no-xmllint -a encoding=UTF-8"
A2XH="a2x -f xhtml --no-xmllint -a encoding=UTF-8" A2XH="a2x -f xhtml --no-xmllint -a encoding=UTF-8"
# Developer webbase # Developer webbase
WEBDIR=$HOME/niconetz WEBDIR=$HOME/niconetz
WEBBASE=software/cdist WEBBASE=$WEBDIR/software/cdist
WEBMAN=$WEBBASE/man/$version
WEBPAGE=${WEBBASE}.mdwn WEBPAGE=${WEBBASE}.mdwn
# Documentation # Documentation
@ -95,17 +98,18 @@ case "$1" in
;; ;;
web) web)
cp README ${WEBDIR}/${WEBPAGE} cp README ${WEBPAGE}
rm -rf ${WEBDIR}/${WEBBASE}/man rm -rf ${WEBMAN}
mkdir -p ${WEBDIR}/${WEBBASE}/man/man1 ${WEBDIR}/${WEBBASE}/man/man7 mkdir -p ${WEBMAN}/man1 ${WEBMAN}/man7
rm -rf ${WEBDIR}/${WEBBASE}/speeches && mkdir ${WEBDIR}/${WEBBASE}/speeches # old stuff
# rm -rf ${WEBDIR}/${WEBBASE}/speeches && mkdir ${WEBDIR}/${WEBBASE}/speeches
# cp ${SPEECHESDIR}/*.pdf ${WEBDIR}/${WEBBASE}/speeches
# git describe > ${WEBDIR}/${WEBBASE}/man/VERSION
cp ${MAN1DSTDIR}/*.html ${WEBDIR}/${WEBBASE}/man/man1 cp ${MAN1DSTDIR}/*.html ${WEBMAN}/man1
cp ${MAN7DSTDIR}/*.html ${WEBDIR}/${WEBBASE}/man/man7 cp ${MAN7DSTDIR}/*.html ${WEBMAN}/man7
cp ${SPEECHESDIR}/*.pdf ${WEBDIR}/${WEBBASE}/speeches
git describe > ${WEBDIR}/${WEBBASE}/man/VERSION
cd ${WEBDIR} && git add ${WEBBASE} cd ${WEBDIR} && git add ${WEBBASE}
cd ${WEBDIR} && git commit -m "cdist update" ${WEBBASE} ${WEBPAGE} cd ${WEBDIR} && git commit -m "cdist update" ${WEBBASE} ${WEBPAGE}
cd ${WEBDIR} && make pub cd ${WEBDIR} && make pub

View file

@ -49,7 +49,7 @@ if grep -q ^Fedora /etc/redhat-release 2>/dev/null; then
exit 0 exit 0
fi fi
# CentOS is also based on Redhat, this return before redhat! # CentOS is also based on Redhat, thus return before redhat!
if grep -q ^CentOS /etc/redhat-release 2>/dev/null; then if grep -q ^CentOS /etc/redhat-release 2>/dev/null; then
echo centos echo centos
exit 0 exit 0

View file

@ -26,12 +26,18 @@ else
file="/$__object_id" file="/$__object_id"
fi fi
regex=$(cat "$__object/parameter/line") if [ -f "$__object/parameter/regex" ]; then
regex=$(cat "$__object/parameter/regex")
else
wrap=$(cat "$__object/parameter/line")
regex="^$wrap\$"
fi
if [ -f "$file" ]; then if [ -f "$file" ]; then
# sh -e is our environment, we know what we do, # sh -e is our environment, we know what we do,
# skip error detection for now # skip error detection for now
set +e set +e
grep -q "^$regex\$" "$file" grep -q "$regex" "$file"
if [ $? -eq 1 ]; then if [ $? -eq 1 ]; then
echo "NOTFOUND" echo "NOTFOUND"
else else

View file

@ -25,7 +25,9 @@ OPTIONAL PARAMETERS
file:: file::
If supplied, use this as the destination file. If supplied, use this as the destination file.
Otherwise the object_id is used. Otherwise the object_id is used.
regex::
If supplied, search for this regex.
Otherwise entire line must be matched.
EXAMPLES EXAMPLES
-------- --------

View file

@ -1 +1,2 @@
file file
regex

View file

@ -27,4 +27,4 @@ require="__package/python-software-properties" \
--source "$__type/files/remove-apt-repository" \ --source "$__type/files/remove-apt-repository" \
--mode 0755 --mode 0755
require="$__self" __apt_update_index require="$__object_name" __apt_update_index

View file

@ -38,5 +38,5 @@ if [ -f "$__object/parameter/comment" ]; then
fi fi
echo "$entry" >> "$__object/parameter/entry" echo "$entry" >> "$__object/parameter/entry"
require="$__self" __autofs_master require="$__object_name" __autofs_master

View file

@ -24,7 +24,7 @@ if [ ! -f "$__object/parameter/header" ]; then
fi fi
[ -d "$__object/files" ] || mkdir "$__object/files" [ -d "$__object/files" ] || mkdir "$__object/files"
require="$__self" __file /etc/auto.master --source "$__object/files/auto.master" \ require="$__object_name" __file /etc/auto.master --source "$__object/files/auto.master" \
--mode 644 \ --mode 644 \
--owner root \ --owner root \
--group root --group root

View file

@ -49,4 +49,4 @@ for property in $(ls .); do
fi fi
done done
require="$__self" __package_$type "$@" require="$__object_name" __package_$type "$@"

View file

@ -0,0 +1,31 @@
#!/bin/sh
#
# 2012 SwellPath, Inc.
# Christian G. Warden <cwarden@xerus.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/>.
#
# Retrieve the status of a rock
#
if [ -f "$__object/parameter/name" ]; then
name="$(cat "$__object/parameter/name")"
else
name="$__object_id"
fi
# Accept luarocks failing if package is not known/installed
luarocks list "$name" | egrep -A1 "^$name$" || exit 0

View file

@ -0,0 +1,52 @@
#!/bin/sh
#
# 2012 SwellPath, Inc.
# Christian G. Warden <cwarden@xerus.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/>.
#
#
# Manage LuaRocks packages
#
if [ -f "$__object/parameter/name" ]; then
name="$(cat "$__object/parameter/name")"
else
name="$__object_id"
fi
state="$(cat "$__object/parameter/state")"
is_installed="$(grep "(installed)" "$__object/explorer/pkg_status" || true)"
case "$state" in
installed)
# Install only if non-existent
if [ -z "$is_installed" ]; then
echo luarocks install \"$name\"
fi
;;
removed)
# Remove only if existent
if [ -n "$is_installed" ]; then
echo luarocks remove \"$name\"
fi
;;
*)
echo "Unknown state: $state" >&2
exit 1
;;
esac

View file

@ -0,0 +1,49 @@
cdist-type__package_luarocks(7)
==============================
Christian G. Warden <cwarden@xerus.org>
NAME
----
cdist-type__package_luarocks - Manage luarocks packages
DESCRIPTION
-----------
LuaRocks is a deployment and management system for Lua modules.
REQUIRED PARAMETERS
-------------------
state::
Either "installed" or "removed".
OPTIONAL PARAMETERS
-------------------
name::
If supplied, use the name and not the object id as the package name.
EXAMPLES
--------
--------------------------------------------------------------------------------
# Ensure luasocket is installed
__package_luarocks luasocket --state installed
# Remove package
__package_luarocks luasocket --state removed
--------------------------------------------------------------------------------
SEE ALSO
--------
- cdist-type(7)
- cdist-type__package(7)
COPYING
-------
Copyright \(C) 2012 SwellPath, Inc. Free use of this software is
granted under the terms of the GNU General Public License version 3 (GPLv3).

View file

@ -0,0 +1,23 @@
#!/bin/sh
#
# 2012 SwellPath, Inc.
# Christian G. Warden <cwarden@xerus.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/>.
#
__package luarocks --state installed
__package make --state installed

View file

@ -0,0 +1 @@
name

View file

@ -0,0 +1 @@
state

View file

@ -38,4 +38,4 @@ if [ ! -f "$__object/parameter/size" ]; then
fi fi
# pull in the type that actually does something with the above parameters # pull in the type that actually does something with the above parameters
require="$__self" __partition_msdos_apply require="$__object_name" __partition_msdos_apply

View file

@ -24,7 +24,7 @@
if [ -f "$__object/parameter/name" ]; then if [ -f "$__object/parameter/name" ]; then
name="$(cat "$__object/parameter/name")" name="$(cat "$__object/parameter/name")"
else else
name="/$__object_id" name="$__object_id"
fi fi
pgrep -x -f "$name" || true pgrep -x -f "$name" || true

View file

@ -50,6 +50,10 @@ __process /usr/sbin/sshd --state stopped --stop "/etc/rc.d/sshd stop"
# Ensure cups is running, which runs with -C ...: # Ensure cups is running, which runs with -C ...:
__process cups --start "/etc/rc.d/cups start" --state running \ __process cups --start "/etc/rc.d/cups start" --state running \
--name "/usr/sbin/cupsd -C /etc/cups/cupsd.conf" --name "/usr/sbin/cupsd -C /etc/cups/cupsd.conf"
# Ensure rpc.statd is running (which usually runs with -L) using a regexp
__process rpcstatd --state running --start "/etc/init.d/statd start" \
--name "rpc.statd.*"
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------

View file

@ -1,8 +1,16 @@
2.0.4: 2.0.5:
* New Type: __package_luarocks (Christian G. Warden)
* Feature: __addifnosuchline supports matching on regular expressions (dan)
* Documentation: (Re)write of the tutorial
2.0.4: 2011-11-18
* Bugfix core: Remove traceback when sending SIGINT (aka Ctrl-C) * Bugfix core: Remove traceback when sending SIGINT (aka Ctrl-C)
* Bugfix core: Accept parameters with - in the name (Steven Armstrong)
* Cleanup: __object_fq variable removed (never used) * Cleanup: __object_fq variable removed (never used)
* Cleanup: Environment variable __self DEPRECATED, use __object_name instead * Cleanup: Environment variable __self DEPRECATED, use __object_name instead
* Cleanup: Environment variable __self scheduled for removal in cdist 2.1 * Cleanup: Environment variable __self scheduled for removal in cdist 2.1
* Documentation: Many examples for use of __remote_* (Steven Armstrong)
* Feature: Automatically require all used objects (Steven Armstrong)
* New Type: __cron (Steven Armstrong) * New Type: __cron (Steven Armstrong)
2.0.3: 2011-10-18 2.0.3: 2011-10-18

View file

@ -1,35 +1,50 @@
#!/bin/sh -e #!/bin/sh
# Nico Schottelius
files="bin/cdist-config doc/changelog" files="doc/changelog lib/cdist/__init__.py"
# Stuff to take care of when doing a release # Stuff to take care of when doing a release
echo "Preparing next release" echo "Preparing next release"
# Ensure documentation builds cleanly # Ensure documentation builds cleanly
./build.sh clean && ./build.sh man echo "Testing documentation..."
./build clean && ./build man || exit 1
# get version # get version
version=$(awk -F'=' '/^__cdist_version/ { print $2 }' bin/cdist-config | sed 's/"//g') changelog_version=$(head -n1 doc/changelog | sed 's/:.*//')
#git_version=$(git describe)
lib_version=$(grep ^VERSION lib/cdist/__init__.py | sed -e 's/.*= //' -e 's/"//g')
echo "Ensure you fixed/prepared version files: $files"
echo "changelog: $changelog_version"
#echo "git: $git_version"
echo "lib: $lib_version"
if [ "$lib_version" != "$changelog_version" ]; then
echo "Messed up versions, not releasing"
exit 1
else
echo "Versions are sane, continuing"
fi
echo "Press enter to continue"
read wait
version=$lib_version
# get target branch # get target branch
branch=${version%.?} branch=${version%.?}
# adjust version and release date
vi $files
# Commit stuff
git commit $files
# add tag # add tag
printf "Enter description for %s>" "$version" printf "Enter tag description for %s> " "$version"
read tagmessage read tagmessage
git tag "$version" -m "$tagmessage" git tag "$version" -m "$tagmessage"
# Import into current version branch # Import into current version branch
echo "git merge into $branch"
git checkout $branch git checkout $branch
git merge master git merge master
git checkout master git checkout master
# Publish manpages and sourcecode # Publish manpages and sourcecode
./build.sh web echo "publising doc/ and code/"
./build.sh pub ./build web
./build pub

View file

@ -13,6 +13,10 @@ TESTS
- multiple defines of object: - multiple defines of object:
- fail if different parameters - fail if different parameters
- succeed if same parameters - succeed if same parameters
- verify that all env variables in doc/man/cdist-reference.text.sh
exist in the right stages
- test DependencyResolver
USER INTERFACE USER INTERFACE
-------------- --------------

View file

@ -1,6 +1,10 @@
- check speech publishing
- and speeches, which may be outdated as well
- write tutorial
- Fix / rewrite cdist-quickstart - Fix / rewrite cdist-quickstart
- write tutorial!!!!!!!!!
- like ccollect! - like ccollect!
- include ssh control master! - include ssh control master!
- add local/ hint (and add to git) - add local/ hint (and add to git)

View file

@ -1,3 +1,10 @@
autorequire:
- objects defined in type manifests should be automatically prerequisites of the current object
- __foo/some-id
__other other-id --state present
=> require="__other/other-id" __foo/some-id
metaparameters: metaparameters:
- steal the metaparameters from puppet: - steal the metaparameters from puppet:

View file

@ -188,9 +188,6 @@ __object_name::
__target_host:: __target_host::
The host we are deploying to. The host we are deploying to.
Available for: initial manifest, type manifest, type gencode Available for: initial manifest, type manifest, type gencode
__target_user::
User to use for authentication on remote host.
Currently static in core.
__type:: __type::
Path to the current type. Path to the current type.
Available for: type manifest, type gencode Available for: type manifest, type gencode

View file

@ -8,38 +8,137 @@ NAME
cdist-tutorial - a guided introduction into cdist cdist-tutorial - a guided introduction into 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.
PREPARING YOUR MACHINE / SETUP This tutorial assumes you are configuring **localhost**, because
------------------------------ it is always available. Just replace **localhost** with your target
host for real life usage.
- ensure sshd is running on the target host:
ssh target_host
- ensure you can login as root
ssh root@target host
- ensure login as root works without keys
(see ssh... manpage)
cdist will do a lot of requests to the target
host, thus you'll have to enter your password
many times, if you don't do this :-)
- speedup processing with ControlMaster option of
ssh
YOUR FIRST CONFIGURATION
------------------------ 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 passwort to the target host,
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.
The file 'conf/manifest/init' is usually the entry point for cdist,
to find out what to configure on which host. All manifests are
essentially shell scripts. Every manifest can use the types known to
cdist, which are usually underline prefixed (__).
DEFINE STATE IN THE INITAL MANIFEST
-----------------------------------
The initial manifest is used to map DEFINE STATE IN THE INITIAL MANIFEST
configurations to a host. ------------------------------------
The **initial manifest** is the entry point for cdist to find out, which
**objects** to configure on the selected host. Objects are instances of
**types**, like in object orientated programming. An object is represented
by the type + slash + object name: ***__file/etc/cdist-configured*** is an
object of the type ***__file*** with the name ***etc/cdist-configured***.
Cdist searches for the initial manifest at **conf/manifest/init** and
executes it as a shell script using **/bin/sh -e**.
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:
--------------------------------------------------------------------------------
__file /etc/cdist-configured
case "$__target_host" in
localhost)
__directory /home/services/kvm-vm --parents yes
;;
esac
--------------------------------------------------------------------------------
This manifest says: Independent of the host, always create the (empty) file
***/etc/cdist-configured***, but create the directory ***/home/services/kvm-vm***,
including all parent directories, only on the host ***localhost***.
As you can see, there is no magic involved, the manifest is simple shell code that
utilises cdist types.
PARTS BELOW HERE ARE TO-BE-DONE
MORE ABOUT TYPES AND OBJECTS
----------------------------
All available types in cdist can be called like normal executables.
USING SOME BASIC TYPES USING SOME BASIC TYPES
---------------------- ----------------------
@ -71,128 +170,14 @@ __debug::
BRANCHES IN HERE?
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 TUNING CDIST
it is always available. Just repace **localhost** with your target ------------
host for real life usage.
- speedup processing with ControlMaster option of
ssh
QUICK START
-----------
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
--------------------------------------------------------------------------------
As soon as you are able to login without passwort to the target host,
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
chmod 0700 conf/manifest/init
# Configure localhost
./bin/cdist config localhost
# Find out that cdist created /etc/cdist-configured
ls -l /etc/cdist-configured
--------------------------------------------------------------------------------
The file 'conf/manifest/init' is usually the entry point for cdist,
to find out what to configure on which host. All manifests are
essentially shell scripts. Every manifest can use the types known to
cdist, which are usually underline prefixed (__).
SEE ALSO SEE ALSO

View file

@ -34,7 +34,7 @@ BANNER = """
"P' "" "" "P' "" ""
""" """
DOT_CDIST = ".cdist" DOT_CDIST = ".cdist"
VERSION = "2.0.3" VERSION = "2.0.4"
import os import os

View file

@ -75,6 +75,7 @@ class Emulator(object):
self.commandline() self.commandline()
self.setup_object() self.setup_object()
self.record_requirements() self.record_requirements()
self.record_auto_requirements()
self.log.debug("Finished %s %s" % (self.cdist_object.path, self.parameters)) self.log.debug("Finished %s %s" % (self.cdist_object.path, self.parameters))
def __init_log(self): def __init_log(self):
@ -97,10 +98,10 @@ class Emulator(object):
for parameter in self.cdist_type.optional_parameters: for parameter in self.cdist_type.optional_parameters:
argument = "--" + parameter argument = "--" + parameter
parser.add_argument(argument, action='store', required=False) parser.add_argument(argument, dest=parameter, action='store', required=False)
for parameter in self.cdist_type.required_parameters: for parameter in self.cdist_type.required_parameters:
argument = "--" + parameter argument = "--" + parameter
parser.add_argument(argument, action='store', required=True) parser.add_argument(argument, dest=parameter, action='store', required=True)
# If not singleton support one positional parameter # If not singleton support one positional parameter
if not self.cdist_type.is_singleton: if not self.cdist_type.is_singleton:
@ -181,3 +182,14 @@ class Emulator(object):
# Record / Append source # Record / Append source
self.cdist_object.source.append(self.object_source) self.cdist_object.source.append(self.object_source)
def record_auto_requirements(self):
"""An object shall automatically depend on all objects that it defined in it's type manifest.
"""
# __object_name is the name of the object whose type manifest is currenlty executed
__object_name = os.environ.get('__object_name', None)
if __object_name:
_object = self.cdist_object.object_from_name(__object_name)
# prevent circular dependencies
if not _object.name in self.cdist_object.requirements:
_object.requirements.append(self.cdist_object.name)

View file

@ -95,6 +95,12 @@ class Local(object):
""" """
assert isinstance(command, (list, tuple)), "list or tuple argument expected, got: %s" % command assert isinstance(command, (list, tuple)), "list or tuple argument expected, got: %s" % command
self.log.debug("Local run: %s", command) self.log.debug("Local run: %s", command)
if env is None:
env = os.environ.copy()
# Export __target_host for use in __remote_{copy,exec} scripts
env['__target_host'] = self.target_host
try: try:
if return_output: if return_output:
return subprocess.check_output(command, env=env).decode() return subprocess.check_output(command, env=env).decode()
@ -114,7 +120,12 @@ class Local(object):
command.append(script) command.append(script)
self.log.debug("Local run script: %s", command) self.log.debug("Local run script: %s", command)
if env:
if env is None:
env = os.environ.copy()
# Export __target_host for use in __remote_{copy,exec} scripts
env['__target_host'] = self.target_host
self.log.debug("Local run script env: %s", env) self.log.debug("Local run script env: %s", env)
try: try:

View file

@ -91,7 +91,7 @@ class Remote(object):
self.rmdir(destination) self.rmdir(destination)
command = self._copy.split() command = self._copy.split()
command.extend(["-r", source, self.target_host + ":" + destination]) command.extend(["-r", source, self.target_host + ":" + destination])
self.run_command(command) self._run_command(command)
def run(self, command, env=None, return_output=False): def run(self, command, env=None, return_output=False):
"""Run the given command with the given environment on the remote side. """Run the given command with the given environment on the remote side.
@ -102,9 +102,9 @@ class Remote(object):
cmd = self._exec.split() cmd = self._exec.split()
cmd.append(self.target_host) cmd.append(self.target_host)
cmd.extend(command) cmd.extend(command)
return self.run_command(cmd, env=env, return_output=return_output) return self._run_command(cmd, env=env, return_output=return_output)
def run_command(self, command, env=None, return_output=False): def _run_command(self, command, env=None, return_output=False):
"""Run the given command with the given environment. """Run the given command with the given environment.
Return the output as a string. Return the output as a string.

View file

@ -22,6 +22,7 @@
import os import os
import shutil import shutil
import cdist
from cdist import test from cdist import test
from cdist.exec import local from cdist.exec import local
from cdist import emulator from cdist import emulator
@ -29,7 +30,6 @@ from cdist import core
local_base_path = test.cdist_base_path local_base_path = test.cdist_base_path
class EmulatorTestCase(test.CdistTestCase): class EmulatorTestCase(test.CdistTestCase):
def setUp(self): def setUp(self):
@ -88,3 +88,67 @@ class EmulatorTestCase(test.CdistTestCase):
emu = emulator.Emulator(argv) emu = emulator.Emulator(argv)
emu.run() emu.run()
# if we get here all is fine # if we get here all is fine
import os.path as op
my_dir = op.abspath(op.dirname(__file__))
fixtures = op.join(my_dir, 'fixtures')
class AutoRequireEmulatorTestCase(test.CdistTestCase):
def setUp(self):
self.temp_dir = self.mkdtemp()
self.target_host = 'localhost'
out_path = self.temp_dir
_local_base_path = fixtures
self.local = local.Local(self.target_host, _local_base_path, out_path)
self.local.create_directories()
self.local.link_emulator(cdist.test.cdist_exec_path)
self.manifest = core.Manifest(self.target_host, self.local)
def tearDown(self):
shutil.rmtree(self.temp_dir)
def test_autorequire(self):
initial_manifest = os.path.join(self.local.manifest_path, "init")
self.manifest.run_initial_manifest(initial_manifest)
cdist_type = core.Type(self.local.type_path, '__saturn')
cdist_object = core.Object(cdist_type, self.local.object_path, 'singleton')
self.manifest.run_type_manifest(cdist_object)
expected = ['__planet/Saturn', '__moon/Prometheus']
self.assertEqual(sorted(cdist_object.requirements), sorted(expected))
class ArgumentsWithDashesTestCase(test.CdistTestCase):
def setUp(self):
self.temp_dir = self.mkdtemp()
self.target_host = 'localhost'
out_path = self.temp_dir
handle, self.script = self.mkstemp(dir=self.temp_dir)
os.close(handle)
_local_base_path = fixtures
self.local = local.Local(self.target_host, _local_base_path, out_path)
self.local.create_directories()
self.local.link_emulator(test.cdist_exec_path)
self.env = {
'PATH': "%s:%s" % (self.local.bin_path, os.environ['PATH']),
'__target_host': self.target_host,
'__global': self.local.out_path,
'__cdist_type_base_path': self.local.type_path, # for use in type emulator
'__manifest': self.local.manifest_path,
'__cdist_manifest': self.script,
}
def tearDown(self):
shutil.rmtree(self.temp_dir)
def test_arguments_with_dashes(self):
argv = ['__arguments_with_dashes', 'some-id', '--with-dash', 'some value']
os.environ.update(self.env)
emu = emulator.Emulator(argv)
emu.run()
cdist_type = core.Type(self.local.type_path, '__arguments_with_dashes')
cdist_object = core.Object(cdist_type, self.local.object_path, 'some-id')
self.assertTrue('with-dash' in cdist_object.parameters)

View file

@ -0,0 +1,3 @@
#!/bin/sh
__saturn

View file

@ -0,0 +1,8 @@
#!/bin/sh
if [ -f "$__object/parameter/name" ]; then
name="(cat "$__object/parameter/name")"
else
name="$__object_id"
echo "$name" > "$__object/parameter/name"
fi

View file

@ -0,0 +1 @@
planet

View file

@ -0,0 +1,8 @@
#!/bin/sh
if [ -f "$__object/parameter/name" ]; then
name="(cat "$__object/parameter/name")"
else
name="$__object_id"
echo "$name" > "$__object/parameter/name"
fi

View file

@ -0,0 +1,4 @@
#!/bin/sh
__planet Saturn
require="__planet/Saturn" __moon Prometheus --planet Saturn

View file

@ -49,7 +49,7 @@ my_name="${0##*/}"
mode="$1"; shift mode="$1"; shift
log() { log() {
#echo "$@" | logger -t "cdist-$my_name-$mode" echo "$@" | logger -t "cdist-$my_name-$mode"
: :
} }
@ -112,7 +112,9 @@ fi
case "$mode" in case "$mode" in
exec) exec)
code="$exec_prefix schroot -c $schroot_name -- $@" # In exec mode the first argument is the __target_host which we already got from env. Get rid of it.
shift
code="$exec_prefix schroot -c $schroot_name -- sh -c '$@'"
;; ;;
copy) copy)
# get directory for given chroot_name # get directory for given chroot_name

View file

@ -0,0 +1,2 @@
This type is used in production in the ETH and utilises a template to generate
the config file.

View file

@ -0,0 +1,46 @@
#!/bin/sh
cat << DONE
#
# D-INFK SANS MANAGED FILE
# ========================
#
# Do not change this file. Changes will be overwritten.
#
# /etc/nslcd.conf
# nslcd configuration file. See nslcd.conf(5)
# for details.
# The user and group nslcd should run as.
uid nslcd
gid nslcd
# The location at which the LDAP server(s) should be reachable.
uri ldaps://ldaps01.ethz.ch
uri ldaps://ldaps02.ethz.ch
uri ldaps://ldaps03.ethz.ch
# The search base
base ou=${ou},ou=inf,ou=auth,o=ethz,c=ch
base passwd ou=users,ou=${ou},ou=inf,ou=auth,o=ethz,c=ch
base group ou=Group,ou=inf,ou=auth,o=ethz,c=ch
base netgroup ou=netgroup,ou=inf,ou=auth,o=ethz,c=ch
binddn cn=REPLACE,ou=ME,ou=WITH,ou=YOUR,o=DETAILS,c=ch
bindpw VERYSECRETPASSWORD
# The LDAP protocol version to use.
#ldap_version 3
# The DN to bind with for normal lookups.
#binddn cn=annonymous,dc=example,dc=net
#bindpw secret
# SSL options
ssl on
tls_reqcert never
# The search scope.
#scope sub
DONE

View file

@ -0,0 +1,22 @@
#
# D-INFK SANS MANAGED FILE
# ========================
#
# Do not change this file. Changes will be overwritten.
#
# /etc/nsswitch.conf
#
passwd: files ldap
group: files ldap
shadow: files ldap
hosts: files dns
networks: files
services: db files
protocols: db files
rpc: db files
ethers: db files
netgroup: files ldap

View file

@ -0,0 +1,39 @@
#!/bin/sh
#
# 2011 Steven Armstrong (steven-cdist at armstrong.cc)
#
# 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/>.
#
#
# Configure nss_ldap for a machine at DINFK.
#
ou="$(cat "$__object/parameter/ou")"
ldap_config="/etc/nslcd.conf"
ldap_package="libnss-ldapd"
# Install required packages
__package "$ldap_package" --state installed
# Generate nss-ldap config file from template
mkdir "$__object/files"
. "$__type/files/nslcd.conf.template" > "$__object/files/nslcd.conf"
__file "$ldap_config" --source "$__object/files/nslcd.conf"
# Configure nsswitch to use ldap
require="__package/$ldap_package __file/$ldap_config" \
__file /etc/nsswitch.conf --source "$__type/files/nsswitch.conf"

View file

@ -0,0 +1 @@
ou