Merge branch 'master' into type__git

This commit is contained in:
Nico Schottelius 2012-12-05 22:46:07 +01:00
commit 5a3dc38e60
34 changed files with 507 additions and 216 deletions

9
build
View file

@ -27,7 +27,7 @@
#set -e #set -e
basedir=${0%/*} basedir=${0%/*}
version=$(git describe) version=$(cd "$basedir" && 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"
@ -331,14 +331,17 @@ eof
done done
;; ;;
web) web-doc)
set -e
rsync -av "${basedir}/docs/web/" "${WEBTOPDIR}" rsync -av "${basedir}/docs/web/" "${WEBTOPDIR}"
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
;;
web)
set -e
$0 web-doc
# Fix ikiwiki, which does not like symlinks for pseudo security # Fix ikiwiki, which does not like symlinks for pseudo security
ssh tee.schottelius.org \ ssh tee.schottelius.org \
"cd /home/services/www/nico/www.nico.schottelius.org/www/software/cdist/man && "cd /home/services/www/nico/www.nico.schottelius.org/www/software/cdist/man &&

View file

@ -34,15 +34,8 @@ fi
state="$(cat "$__object/parameter/state")" state="$(cat "$__object/parameter/state")"
if [ -f "$__object/parameter/started" ]; then
started="$(cat "$__object/parameter/started")"
else
if [ ! "$state" = "present" ]; then
started="false"
else
started="true" started="true"
fi [ -f "$__object/parameter/stopped" ] && started="false"
fi
if [ -f "$__object/parameter/ip" ]; then if [ -f "$__object/parameter/ip" ]; then
ip="$(cat "$__object/parameter/ip")" ip="$(cat "$__object/parameter/ip")"
@ -66,8 +59,8 @@ if [ -f "$__object/parameter/interface" ]; then
interface="$(cat "$__object/parameter/interface")" interface="$(cat "$__object/parameter/interface")"
fi fi
if [ -f "$__object/parameter/devfs-enable" ]; then if [ -f "$__object/parameter/devfs-disable" ]; then
devfsenable="$(cat "$__object/parameter/devfs-enable")" devfsenable="false"
else else
devfsenable="true" devfsenable="true"
fi fi
@ -82,12 +75,12 @@ fi
# is pointless. Treat this as an error. # is pointless. Treat this as an error.
if [ -n "$devfsruleset" -a "$devfsenable" = "false" ]; then if [ -n "$devfsruleset" -a "$devfsenable" = "false" ]; then
exec >&2 exec >&2
echo "Can't have --devfs-ruleset defined without --devfs-enable true." echo "Can't have --devfs-ruleset defined with --devfs-disable"
exit 1 exit 1
fi fi
if [ -f "$__object/parameter/onboot" ]; then if [ -f "$__object/parameter/onboot" ]; then
onboot="$(cat "$__object/parameter/onboot")" onboot="true"
fi fi
if [ -f "$__object/parameter/jaildir" ]; then if [ -f "$__object/parameter/jaildir" ]; then
@ -357,7 +350,3 @@ else # The jail does not currently exist
exit 0 exit 0
fi fi
fi fi
# Debug
#set +x

View file

@ -27,9 +27,6 @@ OPTIONAL PARAMETERS
name:: name::
The name of the jail. Default is to use the object_id as the jail name. The name of the jail. Default is to use the object_id as the jail name.
started::
Either "true" or "false." Defaults to true.
ip:: ip::
The ifconfig style IP/netmask combination to use for the jail guest. If The ifconfig style IP/netmask combination to use for the jail guest. If
the state parameter is "present," this parameter is required. the state parameter is "present," this parameter is required.
@ -41,23 +38,26 @@ interface::
The name of the physical interface on the jail server to bind the jail to. The name of the physical interface on the jail server to bind the jail to.
Defaults to the first interface found in the output of ifconfig -l. Defaults to the first interface found in the output of ifconfig -l.
devfs-enable::
Whether to allow devfs mounting within the jail. Must be "true" or "false."
Defaults to true.
devfs-ruleset:: devfs-ruleset::
The name of the devfs ruleset to associate with the jail. Defaults to The name of the devfs ruleset to associate with the jail. Defaults to
"jailrules." This ruleset must be copied to the server via another type. "jailrules." This ruleset must be copied to the server via another type.
To use this option, devfs-enable must be "true." To use this option, devfs-enable must be "true."
onboot::
Whether to add the jail to rc.conf's jail_list variable. Must be either
"true" or "false." Defaults to false.
jaildir:: jaildir::
The location on the remote server to use for hosting jail filesystems. The location on the remote server to use for hosting jail filesystems.
Defaults to /usr/jail. Defaults to /usr/jail.
BOOLEAN PARAMETERS
------------------
stopped::
Do not start the jail
devfs-disable::
Whether to disallow devfs mounting within the jail
onboot::
Whether to add the jail to rc.conf's jail_list variable.
CAVEATS CAVEATS
------- -------
@ -77,8 +77,8 @@ __jail www --state present --ip "192.168.1.2" --jailbase /my/jail/base.tgz
# Remove the jail called www # Remove the jail called www
__jail www --state absent --jailbase /my/jail/base.tgz __jail www --state absent --jailbase /my/jail/base.tgz
# Ensure that the jail called www is started # The jail www should not be started
__jail www --state present --started true \ __jail www --state present --stopped \
--ip "192.168.1.2 netmask 255.255.255.0" \ --ip "192.168.1.2 netmask 255.255.255.0" \
--jailbase /my/jail/base.tgz --jailbase /my/jail/base.tgz
@ -88,10 +88,10 @@ __jail thisjail --state present --name www \
--jailbase /my/jail/base.tgz --jailbase /my/jail/base.tgz
# Go nuts # Go nuts
__jail lotsofoptions --state present --name testjail --started true \ __jail lotsofoptions --state present --name testjail \
--ip "192.168.1.100 netmask 255.255.255.0" \ --ip "192.168.1.100 netmask 255.255.255.0" \
--hostname "testjail.example.com" --interface "em0" \ --hostname "testjail.example.com" --interface "em0" \
--onboot yes --jailbase /my/jail/base.tgz --jaildir /jails --onboot --jailbase /my/jail/base.tgz --jaildir /jails
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------

View file

@ -0,0 +1,3 @@
onboot
stopped
devfs-disable

View file

@ -1,10 +1,7 @@
name name
started
ip ip
hostname hostname
interface interface
devfs-enable
devfs-ruleset devfs-ruleset
onboot
jaildir jaildir
jailbase jailbase

View file

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

View file

@ -1,15 +0,0 @@
#!/bin/sh
# Get option dstuser if defined
if [ -f "$__object/parameter/dstuser" ]; then
dstuser=`cat "$__object/parameter/dstuser"`
else
dstuser="root"
fi
if id $dstuser >/dev/null 2>&1 ; then
id -ng $dstuser
else
echo "$__object_id: Destination user $dstuser does not exist" >&2
exit 1
fi

View file

@ -1,46 +0,0 @@
cdist-type__ssh_authorized_key(7)
=================================
Aurélien Bondis <aurelien.bondis--@--gmail-DOT-com>
NAME
----
cdist-type__ssh_authorized_key - Sends a user's public key to another user's authorized_keys
DESCRIPTION
-----------
This type sends a rsa key. By default uses root's key and sends it to root's authorized_keys
REQUIRED PARAMETERS
-------------------
None.
OPTIONAL PARAMETERS
-------------------
srcuser:: the user to take the rsa public key from
dstuser:: the user to give the rsa public key to
EXAMPLES
--------
--------------------------------------------------------------------------------
#deploy root's public key
__ssh_authorized_key admin
#deploy bob's public key to alice's authorized_keys
__ssh_authorized_key --srcuser bob --dstuser alice
--------------------------------------------------------------------------------
SEE ALSO
--------
- cdist-type(7)
COPYING
-------
Free use of this software is
granted under the terms of the GNU General Public License version 3 (GPLv3).

View file

@ -1,66 +0,0 @@
#!/bin/sh
#
# 2011 Aurélien Bondis aurelien.bondis AT gmail DOT com
#
# 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/>.
#
#
# This type allows to send a public ssh key from a user to the
# authorized_keys of another
#
#require="__package openssh-server --state present"
# Get option srcuser if defined
if [ -f "$__object/parameter/srcuser" ]; then
srcuser=`cat "$__object/parameter/srcuser"`
fi
# Get option dstuser if defined
if [ -f "$__object/parameter/dstuser" ]; then
dstuser=`cat "$__object/parameter/dstuser"`
else
dstuser="root"
fi
# retrieve destination group
dstgroup=$(cat "$__object/explorer/dstuser_group")
# if a source user is defined, use it's public key
if [ "$srcuser" ]; then
srcrsa="/home/${srcuser}/.ssh/id_rsa.pub"
# if no source user is defined we use root's public key
else
srcrsa="/root/.ssh/id_rsa.pub"
fi
# if a destination user is defined, insert in it's authorized_keys
if [ "$dstuser" ]; then
sshpath="/home/$dstuser/.ssh"
# if no destination user is defined we use root's home
else
sshpath="/root/.ssh"
fi
rsa=`cat $srcrsa`
__directory $sshpath \
--owner $dstuser \
--group $dstgroup \
--mode 700
# the file authorized_keys depends on the .ssh folder
require="__directory${sshpath}" \
__file "$sshpath/authorized_keys" \
--mode 640 \
--owner $dstuser \
--group $dstgroup
# the line added depends on authorized_keys existence
require="__file${sshpath}/authorized_keys" __addifnosuchline sshkey --file \
"$sshpath/authorized_keys" --line "$rsa"

View file

@ -1,2 +0,0 @@
srcuser
dstuser

View file

@ -0,0 +1,45 @@
#!/bin/sh
#
# 2012 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/>.
#
owner="$(cat "$__object/parameter/owner" 2>/dev/null || echo "$__object_id")"
if [ -f "$__object/parameter/file" ]; then
file="$(cat "$__object/parameter/file")"
else
home="$("$__type_explorer/passwd" | cut -d':' -f 6)"
file="$home/.ssh/authorized_keys"
fi
# no authorized_keys file, nothing we could do
[ -f "$file" ] || exit 0
# NOTE: keep variables in sync in manifest/explorer/gencode-*
prefix="#cdist:$__object_name"
suffix="#/cdist:$__object_name"
awk -v prefix="$prefix" -v suffix="$suffix" '{
if (index($0,prefix)) {
triggered=1
}
if (triggered) {
if (index($0,suffix)) {
triggered=0
}
print
}
}' "$file"

View file

@ -0,0 +1,23 @@
#!/bin/sh
#
# 2012 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/>.
#
owner="$(cat "$__object/parameter/owner" 2>/dev/null || echo "$__object_id")"
getent passwd "$owner" || true

View file

@ -0,0 +1,82 @@
#!/bin/sh
#
# 2012 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/>.
#
owner="$(cat "$__object/parameter/owner" 2>/dev/null || echo "$__object_id")"
if [ -f "$__object/parameter/file" ]; then
file="$(cat "$__object/parameter/file")"
else
home="$(cut -d':' -f 6 "$__object/explorer/passwd")"
file="$home/.ssh/authorized_keys"
fi
entry="$__object/files/entry"
if [ ! -s "$__object/explorer/entry" ]; then
state_is='absent'
else
state_is=$(diff -q "$entry" "$__object/explorer/entry" >/dev/null \
&& echo present \
|| echo changed
)
fi
state_should="$(cat "$__object/parameter/state" 2>/dev/null || echo present)"
if [ "$state_should" = "$state_is" ]; then
# Nothing to do, move along
exit 0
fi
remove_entry() {
# NOTE: keep variables in sync in manifest/explorer/gencode-*
prefix="#cdist:$__object_name"
suffix="#/cdist:$__object_name"
cat << DONE
tmpfile=\$(mktemp)
awk -v prefix="$prefix" -v suffix="$suffix" '
{
if (index(\$0,prefix)) {
triggered=1
}
if (triggered) {
if (index(\$0,suffix)) {
triggered=0
}
} else {
print
}
}' "$file" > "\$tmpfile"
mv -f "\$tmpfile" "$file"
DONE
}
case "$state_should" in
present)
if [ "$state_is" = "changed" ]; then
remove_entry
fi
cat << DONE
cat >> "$file" << ${__type##*/}_DONE
$(cat "$entry")
${__type##*/}_DONE
DONE
;;
absent)
remove_entry
;;
esac

View file

@ -0,0 +1,101 @@
cdist-type__ssh_authorized_keys(7)
==================================
Steven Armstrong <steven-cdist--@--armstrong.cc>
NAME
----
cdist-type__ssh_authorized_keys - manage ssh authorized_keys files
DESCRIPTION
-----------
Adds or removes ssh keys from a authorized_keys file.
This type also manages the directory containing the authorized_keys
file and sets strict ownership and permissions. You can disable this feature
with the --noparent boolean parameter.
The existence, ownership and permissions of the authorized_keys file itself are
also managed. This can be disabled with the --nofile boolean parameter. It is
then left to the user to ensure that the file exists and that ownership and
permissions work with ssh.
REQUIRED PARAMETERS
-------------------
key::
the ssh key which shall be added to this authorized_keys file.
Must be a string and can be specified multiple times.
OPTIONAL PARAMETERS
-------------------
owner::
the user owning the authorized_keys file, defaults to object_id.
state::
if the given keys should be 'present' or 'absent', defaults to 'present'.
file::
an alternative destination file, defaults to ~$owner/.ssh/authorized_keys
comment::
an optional comment
BOOLEAN PARAMETERS
------------------
noparent::
don't create or change ownership and permissions of the directory containing
the authorized_keys file
nofile::
don't manage existence, ownership and permissions of the the authorized_keys
file
EXAMPLES
--------
--------------------------------------------------------------------------------
# add your ssh key to remote root's authorized_keys file
__ssh_authorized_keys root \
--key "$(cat ~/.ssh/id_rsa.pub)"
# allow key to login as user-name
__ssh_authorized_keys user-name \
--key "ssh-rsa AXYZAAB3NzaC1yc2..."
# same as above, but with explicit owner, two keys and a comment
__ssh_authorized_keys some-fancy-id \
--owner user-name \
--key "ssh-rsa AXYZAAB3NzaC1yc2..." \
--key "ssh-rsa AZXYAAB3NzaC1yc2..." \
--comment "allow the members of project foo to login"
# same as above, but authorized_keys file in non standard location
__ssh_authorized_keys some-fancy-id \
--file /etc/ssh/keys/user-name/authorized_keys \
--owner user-name \
--key "ssh-rsa AXYZAAB3NzaC1yc2..."
# same as above, but directory and authorized_keys file is created elswhere
__ssh_authorized_keys some-fancy-id \
--file /etc/ssh/keys/user-name/authorized_keys \
--owner user-name \
--noparent \
--nofile \
--key "ssh-rsa AXYZAAB3NzaC1yc2..."
--------------------------------------------------------------------------------
SEE ALSO
--------
- cdist-type(7)
COPYING
-------
Copyright \(C) 2012 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,74 @@
#!/bin/sh
#
# 2012 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/>.
#
owner="$(cat "$__object/parameter/owner" 2>/dev/null || echo "$__object_id")"
state="$(cat "$__object/parameter/present" 2>/dev/null || echo "present")"
if [ -f "$__object/parameter/file" ]; then
file="$(cat "$__object/parameter/file")"
else
home="$(cut -d':' -f 6 "$__object/explorer/passwd")"
if [ -z "$home" ]; then
echo "Failed to get home directory from explorer." >&2
exit 1
fi
file="$home/.ssh/authorized_keys"
fi
if [ ! -f "$__object/parameter/noparent" -o ! -f "$__object/parameter/nofile" ]; then
group="$(cut -d':' -f 4 "$__object/explorer/passwd")"
if [ -z "$group" ]; then
echo "Failed to get owners group from explorer." >&2
exit 1
fi
if [ ! -f "$__object/parameter/noparent" ]; then
# Ensure that the directory in which the authorized_keys shall be exists and
# has the right permissions.
ssh_directory="${file%/*}"
__directory "$ssh_directory" --state present --parents \
--owner "$owner" --group "$group" --mode 0700
export require="__directory/$ssh_directory"
fi
if [ ! -f "$__object/parameter/nofile" ]; then
# Ensure that authorized_keys file exists and has the right permissions.
__file "$file" \
--owner "$owner" \
--group "$group" \
--mode 0600 \
--state exists
fi
fi
# NOTE: keep variables in sync in manifest/explorer/gencode-*
prefix="#cdist:$__object_name"
suffix="#/cdist:$__object_name"
mkdir "$__object/files"
# Generate entry for inclusion in authorized_keys file
entry="$__object/files/entry"
echo "$prefix" > "$entry"
if [ -f "$__object/parameter/comment" ]; then
echo "# $(cat "$__object/parameter/comment")" >> "$entry"
fi
cat "$__object/parameter/key" >> "$entry"
# ensure we have a newline after keys
echo >> "$entry"
echo "$suffix" >> "$entry"

View file

@ -0,0 +1,2 @@
noparent
nofile

View file

@ -0,0 +1,4 @@
owner
state
file
comment

View file

@ -0,0 +1 @@
key

View file

@ -38,7 +38,7 @@ class Context(object):
remote_copy, remote_copy,
remote_exec, remote_exec,
initial_manifest=False, initial_manifest=False,
add_conf_dirs=[], add_conf_dirs=None,
exec_path=sys.argv[0], exec_path=sys.argv[0],
debug=False): debug=False):

View file

@ -186,8 +186,6 @@ class CdistObject(object):
return os.path.join(self.path, "explorer") return os.path.join(self.path, "explorer")
requirements = fsproperty.FileListProperty(lambda obj: os.path.join(obj.absolute_path, 'require')) 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')) 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)) 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)) explorers = fsproperty.DirectoryDictProperty(lambda obj: os.path.join(obj.base_path, obj.explorer_path))

View file

@ -153,7 +153,7 @@ class Explorer(object):
destination = os.path.join(self.remote.type_path, cdist_type.explorer_path) destination = os.path.join(self.remote.type_path, cdist_type.explorer_path)
self.remote.mkdir(destination) self.remote.mkdir(destination)
self.remote.transfer(source, destination) self.remote.transfer(source, destination)
self.remote.run(["chmod", "0700", "%s" % (destination)]) self.remote.run(["chmod", "0700", "%s/*" % (destination)])
self._type_explorers_transferred.append(cdist_type.name) self._type_explorers_transferred.append(cdist_type.name)
def transfer_object_parameters(self, cdist_object): def transfer_object_parameters(self, cdist_object):

View file

@ -23,7 +23,6 @@
import argparse import argparse
import logging import logging
import os import os
import warnings
import sys import sys
import cdist import cdist
@ -93,12 +92,8 @@ class Emulator(object):
def commandline(self): def commandline(self):
"""Parse command line""" """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: for parameter in self.cdist_type.required_parameters:
argument = "--" + parameter argument = "--" + parameter
@ -124,11 +119,6 @@ class Emulator(object):
self.args = parser.parse_args(self.argv[1:]) self.args = parser.parse_args(self.argv[1:])
self.log.debug('Args: %s' % self.args) 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): def setup_object(self):
# Setup object_id - FIXME: unset / do not setup anymore! # Setup object_id - FIXME: unset / do not setup anymore!
@ -185,18 +175,10 @@ class Emulator(object):
def record_requirements(self): def record_requirements(self):
"""record requirements""" """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: 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'] requirements = self.env['require']
self.log.debug("reqs = " + requirements)
for requirement in requirements.split(" "): for requirement in requirements.split(" "):
# Ignore empty fields - probably the only field anyway # Ignore empty fields - probably the only field anyway
if len(requirement) == 0: continue if len(requirement) == 0: continue
@ -205,10 +187,11 @@ class Emulator(object):
cdist_object = self.cdist_object.object_from_name(requirement) cdist_object = self.cdist_object.object_from_name(requirement)
self.log.debug("Recording requirement: " + requirement) self.log.debug("Recording requirement: " + requirement)
# Save the sanitised version, not the user supplied one # Save the sanitised version, not the user supplied one
# (__file//bar => __file/bar) # (__file//bar => __file/bar)
# This ensures pattern matching is done against sanitised list # 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): def record_auto_requirements(self):
"""An object shall automatically depend on all objects that it defined in it's type manifest. """An object shall automatically depend on all objects that it defined in it's type manifest.

View file

@ -23,6 +23,7 @@
import io import io
import os import os
import sys import sys
import re
import subprocess import subprocess
import shutil import shutil
import logging import logging
@ -37,7 +38,7 @@ class Local(object):
Directly accessing the local side from python code is a bug. Directly accessing the local side from python code is a bug.
""" """
def __init__(self, target_host, out_path, exec_path, add_conf_dirs=[], cache_dir=None): def __init__(self, target_host, out_path, exec_path, add_conf_dirs=None, cache_dir=None):
self.target_host = target_host self.target_host = target_host
self.out_path = out_path self.out_path = out_path
@ -92,6 +93,12 @@ class Local(object):
if self.home_dir: if self.home_dir:
self.conf_dirs.append(self.home_dir) self.conf_dirs.append(self.home_dir)
# Add directories defined in the CDIST_PATH environment variable
if 'CDIST_PATH' in os.environ:
cdist_path_dirs = re.split(r'(?<!\\):', os.environ['CDIST_PATH'])
cdist_path_dirs.reverse()
self.conf_dirs.extend(cdist_path_dirs)
# Add user supplied directories # Add user supplied directories
if self._add_conf_dirs: if self._add_conf_dirs:
self.conf_dirs.extend(self._add_conf_dirs) self.conf_dirs.extend(self._add_conf_dirs)

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- 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. # This file is part of cdist.
# #
@ -77,6 +77,7 @@ class DependencyResolver(object):
lists of all dependencies including the key object itself. lists of all dependencies including the key object itself.
""" """
if self._dependencies is None: if self._dependencies is None:
log.info("Resolving dependencies...")
self._dependencies = d = {} self._dependencies = d = {}
self._preprocess_requirements() self._preprocess_requirements()
for name,cdist_object in self.objects.items(): for name,cdist_object in self.objects.items():
@ -109,21 +110,10 @@ class DependencyResolver(object):
raise RequirementNotFoundError(pattern) raise RequirementNotFoundError(pattern)
def _preprocess_requirements(self): def _preprocess_requirements(self):
"""Find all before, after and autorequire dependencies and merge them """Find all autorequire dependencies and merge them to be just requirements
to be just requirements for further processing. for further processing.
""" """
for cdist_object in self.objects.values(): 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: if cdist_object.autorequire:
# The objects (children) that this cdist_object (parent) defined # The objects (children) that this cdist_object (parent) defined
# in it's type manifest shall inherit all explicit requirements # in it's type manifest shall inherit all explicit requirements

View file

@ -122,6 +122,25 @@ class LocalTestCase(test.CdistTestCase):
self.assertTrue(os.path.isdir(our_type_dir)) self.assertTrue(os.path.isdir(our_type_dir))
def test_conf_dir_from_path_linking(self):
"""Ensure that links are correctly created for types in conf directories which are defined in CDIST_PATH"""
test_type="__cdist_test_type"
os.environ['CDIST_PATH'] = conf_dir
link_test_local = local.Local(
target_host='localhost',
out_path=self.out_path,
exec_path=test.cdist_exec_path,
)
link_test_local._create_conf_path_and_link_conf_dirs()
our_type_dir = os.path.join(link_test_local.type_path, test_type)
self.assertTrue(os.path.isdir(our_type_dir))
### other tests ### other tests
def test_run_success(self): def test_run_success(self):

View file

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

View file

@ -4,13 +4,19 @@ Changelog
* Changes are always commented with their author in (braces) * Changes are always commented with their author in (braces)
* Exception: No braces means author == Nico Schottelius * Exception: No braces means author == Nico Schottelius
next: 2.1.0:
* Core: Ensure global and type explorers are executable * Core: Ensure global explorers are executable
* Core: Ensure type explorers are executable (Steven Armstrong)
* Type __rvm_gemset: Change parameter "default" to be boolean * Type __rvm_gemset: Change parameter "default" to be boolean
* New Type: __user_groups (Steven Armstrong) * New Type: __user_groups (Steven Armstrong)
* Type __user: Remove --groups support (now provided by __user_groups) * Type __user: Remove --groups support (now provided by __user_groups)
* Type __apt_ppa: Bugfix: Installeded ppa detection (Steven Armstrong) * Type __apt_ppa: Bugfix: Installeded ppa detection (Steven Armstrong)
* Core: Support for --after and --before parameters * Type __jail: Change optional parameter "started" to boolean "stopped" parameter,
change optional parameter "devfs-enable" to boolean "devfs-disable" parameter and
change optional parameter "onboot" to boolean.
* New Type: __ssh_authorized_keys (Steven Armstrong)
* Remove Type __ssh_authorized_key: Superseeded by __ssh_authorized_keys
* Support for CDIST_PATH (Steven Armstrong)
2.1.0pre8: 2012-11-15 2.1.0pre8: 2012-11-15
* Type cleanup: __apt_ppa, __apt_ppa_update_index, __file, * 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

@ -14,7 +14,7 @@ cdist [-h] [-V]
cdist banner cdist banner
cdist config [-h] [-d] [-V] [-c CDIST_HOME] [-i MANIFEST] [-p] [-s] host [host ...] cdist config [-h] [-d] [-V] [-c CONF_DIR] [-i MANIFEST] [-p] [-s] host [host ...]
@ -43,9 +43,14 @@ Configure a system
-h, --help:: -h, --help::
Show the help screen Show the help screen
-c CDIST_HOME, --cdist-home CDIST_HOME:: -c CONF_DIR, --conf-dir CONF_DIR::
Instead of using the parent of the bin directory as cdist home, Add a configuration directory. Can be specified multiple times.
use the specified directory If configuration directories contain conflicting types, explorers or
manifests, then the last one found is used. Additionally this can also
be configured by setting the CDIST_PATH environment variable to a colon
delimited list of config directories. Directories given with the
--conf-dir argument have higher precedence over those set through the
environment variable.
-d, --debug:: -d, --debug::
Enable debug output Enable debug output

View file

@ -30,6 +30,15 @@ Host *
ControlPersist 10 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 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/) [cfengine](http://www.cfengine.org/)
and [puppet](http://www.puppetlabs.com/). and [puppet](http://www.puppetlabs.com/).
* [[Why should I use cdist?|why]]
* [[Documentation|documentation]] * [[Documentation|documentation]]
* [[Supported Operating Systems|os]] * [[Supported Operating Systems|os]]
* [[Installation|install]] * [[Installation|install]]

View file

@ -42,6 +42,8 @@ To upgrade to the lastet version do
* The types **\_\_autofs**, **\_\_autofs_map** and **\_\_autofs_reload** have been removed * The types **\_\_autofs**, **\_\_autofs_map** and **\_\_autofs_reload** have been removed
(no maintainer, no users) (no maintainer, no users)
* Type **\_\_user**: Parameter --groups removed (use the new \_\_user_groups type) * Type **\_\_user**: Parameter --groups removed (use the new \_\_user_groups type)
* Type **\_\_ssh_authorized_key** has been replaced by more flexible type
**\_\_ssh_authorized_keys**
* require="" is deprecated: Use --after and --before as parameters instead * require="" is deprecated: Use --after and --before as parameters instead
### Updating from 1.7 to 2.0 ### Updating from 1.7 to 2.0

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]]