Merge branch 'master' into notifications

This commit is contained in:
Nico Schottelius 2013-11-25 22:54:36 +01:00
commit d00947711d
250 changed files with 4447 additions and 1653 deletions

3
.gitignore vendored
View file

@ -26,3 +26,6 @@ cdist/version.py
/cdist-*.tar.gz /cdist-*.tar.gz
/pkg /pkg
/src /src
build
.lock-*
.git-current-branch

252
Makefile Normal file
View file

@ -0,0 +1,252 @@
#
# 2013 Nico Schottelius (nico-cdist at schottelius.org)
#
# This file is part of cdist.
#
# cdist is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# cdist is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with cdist. If not, see <http://www.gnu.org/licenses/>.
#
#
A2XM=a2x -f manpage --no-xmllint -a encoding=UTF-8
A2XH=a2x -f xhtml --no-xmllint -a encoding=UTF-8
helper=./bin/build-helper
MANDIR=docs/man
SPEECHDIR=docs/speeches
TYPEDIR=cdist/conf/type
WEBSRCDIR=docs/web
WEBDIR=$$HOME/www.nico.schottelius.org
WEBBLOG=$(WEBDIR)/blog
WEBBASE=$(WEBDIR)/software/cdist
WEBPAGE=$(WEBBASE).mdwn
CHANGELOG_VERSION=$(shell $(helper) changelog-version)
CHANGELOG_FILE=docs/changelog
PYTHON_VERSION=cdist/version.py
################################################################################
# Manpages
#
MAN1DSTDIR=$(MANDIR)/man1
MAN7DSTDIR=$(MANDIR)/man7
# Manpages #1: Types
# Use shell / ls to get complete list - $(TYPEDIR)/*/man.text does not work
MANTYPESRC=$(shell ls $(TYPEDIR)/*/man.text)
# replace first path component
MANTYPEPREFIX=$(subst $(TYPEDIR)/,$(MAN7DSTDIR)/cdist-type,$(MANTYPESRC))
# replace man.text with .7 or .html
MANTYPEMAN=$(subst /man.text,.7,$(MANTYPEPREFIX))
MANTYPEHTML=$(subst /man.text,.html,$(MANTYPEPREFIX))
MANTYPEALL=$(MANTYPEMAN) $(MANTYPEHTML)
# Link manpage so A2XH does not create man.html but correct named file
$(MAN7DSTDIR)/cdist-type%.text: $(TYPEDIR)/%/man.text
ln -sf "../../../$^" $@
# Manpages #2: reference
MANREF=$(MAN7DSTDIR)/cdist-reference.text
MANREFSH=$(MANDIR)/cdist-reference.text.sh
MANREFMAN=$(MANREF:.text=.7)
MANREFHTML=$(MANREF:.text=.html)
MANREFALL=$(MANREFMAN) $(MANREFHTML)
$(MANREF): $(MANREFSH)
$(MANREFSH)
# Manpages #3: static pages
MAN1STATIC=$(shell ls $(MAN1DSTDIR)/*.text)
MAN7STATIC=$(shell ls $(MAN7DSTDIR)/*.text)
MANSTATICMAN=$(MAN1STATIC:.text=.1) $(MAN7STATIC:.text=.7)
MANSTATICHTML=$(MAN1STATIC:.text=.html) $(MAN7STATIC:.text=.html)
MANSTATICALL=$(MANSTATICMAN) $(MANSTATICHTML)
# Manpages #4: generic part
# Creating the type manpage
%.1 %.7: %.text
$(A2XM) $^
# Creating the type html page
%.html: %.text
$(A2XH) $^
man: $(MANTYPEALL) $(MANREFALL) $(MANSTATICALL)
# Manpages #5: release part
MANWEBDIR=$(WEBBASE)/man/$(CHANGELOG_VERSION)
man-dist: man check-date
rm -rf "${MANWEBDIR}"
mkdir -p "${MANWEBDIR}/man1" "${MANWEBDIR}/man7"
cp ${MAN1DSTDIR}/*.html ${MAN1DSTDIR}/*.css ${MANWEBDIR}/man1
cp ${MAN7DSTDIR}/*.html ${MAN7DSTDIR}/*.css ${MANWEBDIR}/man7
cd ${MANWEBDIR} && git add . && git commit -m "cdist manpages update: $(CHANGELOG_VERSION)" || true
man-fix-link: web-pub
# 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 && rm -f latest && ln -sf "$(CHANGELOG_VERSION)" latest"
################################################################################
# Speeches
#
SPEECHESOURCES=$(SPEECHDIR)/*.tex
SPEECHES=$(SPEECHESOURCES:.tex=.pdf)
SPEECHESWEBDIR=$(WEBBASE)/speeches
# Create speeches and ensure Toc is up-to-date
$(SPEECHDIR)/%.pdf: $(SPEECHDIR)/%.tex
pdflatex -output-directory $(SPEECHDIR) $^
pdflatex -output-directory $(SPEECHDIR) $^
pdflatex -output-directory $(SPEECHDIR) $^
speeches: $(SPEECHES)
speeches-dist: speeches
rm -rf "${SPEECHESWEBDIR}"
mkdir -p "${SPEECHESWEBDIR}"
cp ${SPEECHES} "${SPEECHESWEBDIR}"
cd ${SPEECHESWEBDIR} && git add . && git commit -m "cdist speeches updated" || true
################################################################################
# Website
#
BLOGFILE=$(WEBBLOG)/cdist-$(CHANGELOG_VERSION)-released.mdwn
$(BLOGFILE): $(CHANGELOG_FILE)
$(helper) blog $(CHANGELOG_VERSION) $(BLOGFILE)
web-blog: $(BLOGFILE)
web-doc:
# Go to top level, because of cdist.mdwn
rsync -av "$(WEBSRCDIR)/" "${WEBBASE}/.."
cd "${WEBBASE}/.." && git add cdist* && git commit -m "cdist doc update" cdist* || true
web-dist: web-blog web-doc
web-pub: web-dist man-dist speeches-dist
cd "${WEBDIR}" && make pub
web-release-all: man-fix-link
################################################################################
# Release: Mailinglist
#
ML_FILE=.lock-ml
# Only send mail once - lock until new changelog things happened
$(ML_FILE): $(CHANGELOG_FILE)
$(helper) ml-release $(CHANGELOG_VERSION)
touch $@
ml-release: $(ML_FILE)
################################################################################
# Release: Freecode
#
FREECODE_FILE=.lock-freecode
$(FREECODE_FILE): $(CHANGELOG_FILE)
$(helper) freecode-release $(CHANGELOG_VERSION)
touch $@
freecode-release: $(FREECODE_FILE)
################################################################################
# pypi
#
pypi-release: man $(PYTHON_VERSION)
python3 setup.py sdist upload
touch $@
################################################################################
# archlinux
#
ARCHLINUX_FILE=.lock-archlinux
ARCHLINUXTAR=cdist-$(CHANGELOG_VERSION)-1.src.tar.gz
$(ARCHLINUXTAR): PKGBUILD
makepkg -c --source
PKGBUILD: PKGBUILD.in $(PYTHON_VERSION)
./PKGBUILD.in $(CHANGELOG_VERSION)
$(ARCHLINUX_FILE): $(ARCHLINUXTAR) $(PYTHON_VERSION)
burp -c system $(ARCHLINUXTAR)
touch $@
archlinux-release: $(ARCHLINUX_FILE)
################################################################################
# Release
#
$(PYTHON_VERSION): .git/refs/heads/master
$(helper) version
# Code that is better handled in a shell script
check-%:
$(helper) $@
release:
$(helper) $@
################################################################################
# Cleanup
#
clean:
rm -f $(MAN7DSTDIR)/cdist-reference.text
find "$(MANDIR)" -mindepth 2 -type l \
-o -name "*.1" \
-o -name "*.7" \
-o -name "*.html" \
-o -name "*.xml" \
| xargs rm -f
find * -name __pycache__ | xargs rm -rf
# Archlinux
rm -f cdist-*.pkg.tar.xz cdist-*.tar.gz
rm -rf pkg/ src/
rm -f MANIFEST PKGBUILD
rm -rf dist/
distclean: clean
rm -f cdist/version.py
################################################################################
# Misc
#
# The pub is Nico's "push to all git remotes" way ("make pub")
pub:
for remote in "" github sf; do \
echo "Pushing to $$remote"; \
git push --mirror $$remote; \
done
test:
$(helper) $@

View file

@ -1,6 +1,6 @@
#!/bin/sh #!/bin/sh
version=$(git describe) version="$1"
outfile=${0%.in} outfile=${0%.in}
cat << eof > "${outfile}" cat << eof > "${outfile}"

298
bin/build-helper Executable file
View file

@ -0,0 +1,298 @@
#!/bin/sh
#
# 2011-2013 Nico Schottelius (nico-cdist at schottelius.org)
#
# This file is part of cdist.
#
# cdist is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# cdist is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with cdist. If not, see <http://www.gnu.org/licenses/>.
#
#
# This file contains the heavy lifting found usually in the Makefile
#
basedir=${0%/*}/../
# Change to checkout directory
cd "$basedir"
version=$(git describe)
option=$1; shift
case "$option" in
changelog-changes)
if [ "$#" -eq 1 ]; then
start=$1
else
start="[[:digit:]]"
fi
end="[[:digit:]]"
awk -F: "BEGIN { start=0 }
{
if(start == 0) {
if (\$0 ~ /^$start/) {
start = 1
}
} else {
if (\$0 ~ /^$end/) {
exit
} else {
print \$0
}
}
}" "$basedir/docs/changelog"
;;
changelog-version)
# get version from changelog
grep '^[[:digit:]]' "$basedir/docs/changelog" | head -n1 | sed 's/:.*//'
;;
check-date)
# verify date in changelog is today
date_today="$(date +%Y-%m-%d)"
date_changelog=$(grep '^[[:digit:]]' "$basedir/docs/changelog" | head -n1 | sed 's/.*: //')
if [ "$date_today" != "$date_changelog" ]; then
echo "Date in changelog is not today"
echo "Changelog: $date_changelog"
exit 1
fi
;;
check-unittest)
"$0" test
;;
blog)
version=$1; shift
blogfile=$1; shift
dir=${blogfile%/*}
file=${blogfile##*/}
cat << eof > "$blogfile"
[[!meta title="Cdist $version released"]]
Here's a short overview about the changes found in version ${version}:
eof
$0 changelog-changes "$version" >> "$blogfile"
cat << eof >> "$blogfile"
For more information visit the [[cdist homepage|software/cdist]].
[[!tag cdist config unix]]
eof
cd "$dir"
git add "$file"
# Allow git commit to fail if there are no changes
git commit -m "cdist blog update: $version" "$blogfile" || true
;;
ml-release)
version=$1; shift
to_a=cdist
to_d=l.schottelius.org
to=${to_a}@${to_d}
from_a=nico-cdist
from_d=schottelius.org
from=${from_a}@${from_d}
(
cat << eof
From: Nico -telmich- Schottelius <$from>
To: cdist mailing list <$to>
Subject: cdist $version released
Hello .*,
cdist $version has been released with the following changes:
eof
"$0" changelog-changes "$version"
cat << eof
Cheers,
Nico
--
Automatisation at its best level. With cdist.
eof
) | /usr/sbin/sendmail -f "$from" "$to"
;;
freecode-release)
version=$1; shift
api_token=$(awk '/machine freecode login/ { print $8 }' ~/.netrc)
printf "Enter tag list for freecode release %s> " "$version"
read taglist
printf "Enter changelog for freecode release %s> " "$version"
read changelog
echo "Submit preview"
cat << eof
tag_list = $taglist
changelog = $changelog
version = $version
eof
printf "Press enter to submit to freecode> "
read dummy
cat << eof | cfreecode-api release-add cdist
{
"auth_code": "$api_token",
"release": {
"tag_list": "$taglist",
"version": "$version",
"changelog": "$changelog",
"hidden_from_frontpage": false
}
}
eof
;;
release-git-tag)
target_version=$($0 changelog-version)
if git rev-parse --verify refs/tags/$target_version; then
echo "Tag for $target_version exists, aborting"
exit 1
fi
printf "Enter tag description for ${target_version}: "
read tagmessage
git tag "$target_version" -m "$$tagmessage"
;;
release)
set -e
target_version=$($0 changelog-version)
target_branch=$($0 version-branch)
echo "Beginning release process for $target_version"
# First check everything is sane
"$0" check-date
"$0" check-unittest
# Generate version file to be included in packaging
"$0" version
# Ensure the git status is clean, else abort
if ! git diff-index --name-only --exit-code HEAD ; then
echo "Unclean tree, see files above, aborting"
exit 1
fi
# Ensure we are on the master branch
if [ "$(git rev-parse --abbrev-ref HEAD)" != "master" ]; then
echo "Releases are happening from the master branch, aborting"
exit 1
fi
# Ensure version branch exists
if ! git rev-parse --verify refs/heads/$target_branch 2>/dev/null; then
git branch "$target_branch"
fi
# Merge master branch into version branch
git checkout "$target_branch"
git merge master
# Verify that after the merge everything works
"$0" check-date
"$0" check-unittest
# Generate man pages (indirect check if they build)
make man
# Generate speeches (indirect check if they build)
make speeches
#############################################################
# Everything green, let's do the release
# Tag the current commit
"$0" release-git-tag
# Also merge back the version branch
git checkout master
git merge "$target_branch"
# Publish git changes
make pub
# publish man, speeches, website
make web-release-all
# Ensure that pypi release has the right version
"$0" version
# Create and publish package for pypi
make pypi-release
# Archlinux release is based on pypi
make archlinux-release
# Announce change on Freecode
make freecode-release
# Announce change on ML
make ml-release
cat << eof
Manual steps post release:
- linkedin
- hackernews
- reddit
- twitter
eof
;;
test)
export PYTHONPATH="$(pwd -P)"
if [ $# -lt 1 ]; then
python3 -m cdist.test
else
python3 -m unittest "$@"
fi
;;
version-branch)
"$0" changelog-version | cut -d. -f '1,2'
;;
version)
echo "VERSION = \"$(git describe)\"" > cdist/version.py
;;
*)
echo "Unknown helper target $@ - aborting"
exit 1
;;
esac

View file

@ -25,7 +25,7 @@ dir=${0%/*}
# Ensure version is present - the bundled/shipped version contains a static version, # Ensure version is present - the bundled/shipped version contains a static version,
# the git version contains a dynamic version # the git version contains a dynamic version
"$dir/../build" version "$dir/build-helper" version
libdir=$(cd "${dir}/../" && pwd -P) libdir=$(cd "${dir}/../" && pwd -P)
export PYTHONPATH="${libdir}" export PYTHONPATH="${libdir}"

414
build
View file

@ -1,414 +0,0 @@
#!/bin/sh
#
# 2011-2012 Nico Schottelius (nico-cdist at schottelius.org)
#
# This file is part of cdist.
#
# cdist is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# cdist is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with cdist. If not, see <http://www.gnu.org/licenses/>.
#
#
# Push a directory to a target, both sides have the same name (i.e. explorers)
# or
# Pull a directory from a target, both sides have the same name (i.e. explorers)
#
# exit on any error
#set -e
basedir=${0%/*}
version=$(cd "$basedir" && git describe)
# Manpage and HTML
A2XM="a2x -f manpage --no-xmllint -a encoding=UTF-8"
A2XH="a2x -f xhtml --no-xmllint -a encoding=UTF-8"
# Developer webbase
WEBDIR=$HOME/www.nico.schottelius.org
WEBBLOG=$WEBDIR/blog
WEBTOPDIR=$WEBDIR/software
WEBBASE=$WEBTOPDIR/cdist
WEBMAN=$WEBBASE/man/$version
WEBPAGE=${WEBBASE}.mdwn
# Documentation
MANDIR=docs/man
MAN1DSTDIR=${MANDIR}/man1
MAN7DSTDIR=${MANDIR}/man7
SPEECHESDIR=docs/speeches
# Change to checkout directory
cd "$basedir"
case "$1" in
man)
set -e
"$0" mangen
"$0" mantype
"$0" manbuild
;;
manbuild)
trap abort INT
abort() {
kill 0
}
for section in 1 7; do
for src in ${MANDIR}/man${section}/*.text; do
manpage="${src%.text}.$section"
if [ ! -f "$manpage" -o "$manpage" -ot "$src" ]; then
echo "Compiling man page for $src"
$A2XM "$src"
fi
htmlpage="${src%.text}.html"
if [ ! -f "$htmlpage" -o "$htmlpage" -ot "$src" ]; then
echo "Compiling html page for $src"
$A2XH "$src"
fi
done
done
;;
mantype)
for mansrc in cdist/conf/type/*/man.text; do
dst="$(echo $mansrc | sed -e 's;cdist/conf/;cdist-;' -e 's;/;;' -e 's;/man;;' -e 's;^;docs/man/man7/;')"
ln -sf "../../../$mansrc" "$dst"
done
;;
mangen)
${MANDIR}/cdist-reference.text.sh
;;
man-pub)
$0 man
version=$($0 changelog-version)
rm -rf "${WEBMAN}"
mkdir -p "${WEBMAN}/man1" "${WEBMAN}/man7"
cp ${MAN1DSTDIR}/*.html ${MAN1DSTDIR}/*.css ${WEBMAN}/man1
cp ${MAN7DSTDIR}/*.html ${MAN7DSTDIR}/*.css ${WEBMAN}/man7
cd ${WEBMAN} && git add . && git commit -m "Cdist Manpage update: $version"
;;
dist)
set -e
# Do the checks
$0 dist-check
# Git changes - everything depends on this
$0 dist-tag
$0 dist-branch-merge
# Pypi first - is the base for others
$0 dist-pypi
# Archlinux depends on successful pypi ;-)
$0 dist-archlinux
# Update website (includes documentation)
$0 web
# Update manpages on website
$0 man-pub
# update git repos
$0 pub
$0 dist-blog
$0 dist-freecode
$0 dist-ml
$0 dist-manual
;;
changelog-changes)
awk -F: 'BEGIN { start=0 } { if ($0 ~ /^[[:digit:]]/) { if(start == 0) {start = 1 } else { exit } } else { if(start==1) {print $0 }} }' "$basedir/docs/changelog"
;;
changelog-version)
# get version from changelog and ensure it's not already present
grep '^[[:digit:]]' "$basedir/docs/changelog" | head -n1 | sed 's/:.*//'
;;
dist-check)
set -e
echo "Verifying documentation building works ..."
$0 clean
$0 man
changelog_version=$($0 changelog-version)
echo "Target version from changelog: $changelog_version"
if git show --quiet $changelog_version >/dev/null 2>&1; then
echo "Version $changelog_version already exists, aborting."
exit 1
fi
# verify date in changelog
date_today="$(date +%Y-%m-%d)"
date_changelog=$(grep '^[[:digit:]]' "$basedir/docs/changelog" | head -n1 | sed 's/.*: //')
if [ "$date_today" != "$date_changelog" ]; then
echo "Date in changelog is not today"
echo "Changelog: $date_changelog"
exit 1
fi
;;
blog)
version=$($0 changelog-version)
blogfile=$WEBBLOG/cdist-${version}-released.mdwn
cat << eof > "$blogfile"
[[!meta title="Cdist $version released"]]
Here's a short overview about the changes found in this release:
eof
$0 changelog-changes >> "$blogfile"
cat << eof >> "$blogfile"
For more information visit the [[cdist homepage|software/cdist]].
[[!tag cdist config unix]]
eof
;;
dist-blog)
$0 blog
version=$($0 changelog-version)
file=cdist-${version}-released.mdwn
cd "$WEBBLOG"
git add "$file"
git commit -m "New cdist version (blogentry): $version" "$file"
git push
;;
dist-ml)
$0 blog
version=$($0 changelog-version)
to_a=cdist
to_d=l.schottelius.org
to=${to_a}@${to_d}
from_a=nico-cdist
from_d=schottelius.org
from=${from_a}@${from_d}
(
cat << eof
From: Nico -telmich- Schottelius <$from>
To: cdist mailing list <$to>
Subject: cdist $version released
Hello .*,
cdist $version has been released with the following changes:
eof
"$0" changelog-changes
cat << eof
Cheers,
Nico
--
Automatisation at its best level. With cdist.
eof
) | /usr/sbin/sendmail -f "$from" "$to"
;;
dist-manual)
cat << notes
To be done manually...
- linkedin entry
notes
;;
dist-tag)
version=$($0 changelog-version)
# add tag
printf "Enter tag description for %s> " "$version"
read tagmessage
git tag "$version" -m "$tagmessage"
;;
dist-branch-merge)
version=$($0 changelog-version)
target_branch=${version%\.*}
current_branch=$(git rev-parse --abbrev-ref HEAD)
if [ "$target_branch" = "$current_branch" ]; then
echo "Skipping merge, already on destination branch"
else
printf "Press enter to git merge $current_branch into \"$target_branch\" > "
read prompt
git checkout "$target_branch"
git merge "$current_branch"
git checkout "$current_branch"
fi
;;
dist-archlinux)
$0 dist-archlinux-makepkg
$0 dist-archlinux-aur-upload
;;
dist-archlinux-makepkg)
./PKGBUILD.in
makepkg -c --source
;;
dist-archlinux-aur-upload)
version=$($0 changelog-version)
tar=cdist-${version}-1.src.tar.gz
burp -c system "$tar"
;;
dist-freecode)
version=$($0 changelog-version)
api_token=$(awk '/machine freecode login/ { print $8 }' ~/.netrc)
printf "Enter tag list for freecode release %s> " "$version"
read taglist
printf "Enter changelog for freecode release %s> " "$version"
read changelog
echo "Submit preview"
cat << eof
tag_list = $taglist
changelog = $changelog
version = $version
eof
printf "Press enter to submit to freecode> "
read dummy
cat << eof | cfreecode-api release-add cdist
{
"auth_code": "$api_token",
"release": {
"tag_list": "$taglist",
"version": "$version",
"changelog": "$changelog",
"hidden_from_frontpage": false
}
}
eof
;;
dist-pypi)
$0 man
$0 version
python3 setup.py sdist upload
;;
speeches)
cd "$SPEECHESDIR"
for speech in *tex; do
pdflatex "$speech"
pdflatex "$speech"
pdflatex "$speech"
done
;;
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 &&
rm -f latest && ln -sf "$version" latest"
;;
p|pu|pub)
for remote in "" github sf; do
echo "Pushing to $remote"
git push --mirror $remote
done
;;
clean)
rm -f ${MAN7DSTDIR}/cdist-reference.text
find "${MANDIR}" -mindepth 2 -type l \
-o -name "*.1" \
-o -name "*.7" \
-o -name "*.html" \
-o -name "*.xml" \
| xargs rm -f
find * -name __pycache__ | xargs rm -rf
;;
clean-dist)
rm -f cdist/version.py MANIFEST PKGBUILD
rm -rf cache/ dist/
# Archlinux
rm -f cdist-*.pkg.tar.xz cdist-*.tar.gz
rm -rf pkg/ src/
;;
very-clean)
$0 clean
$0 clean-dist
;;
test)
shift # skip t
export PYTHONPATH="$(pwd -P)"
if [ $# -lt 1 ]; then
python3 -m cdist.test
else
python3 -m unittest "$@"
fi
;;
version)
echo "VERSION=\"$version\"" > cdist/version.py
;;
*)
echo ''
echo 'Welcome to cdist!'
echo ''
echo 'Here are the possible targets:'
echo ''
echo ' clean: Remove build stuff'
echo ' man: Build manpages (requires Asciidoc)'
echo ' test: Run tests'
echo ''
echo ''
echo "Unknown target, \"$1\"" >&2
exit 1
;;
esac

View file

@ -40,13 +40,20 @@ BANNER = """
"8888P' `"888*"" R888" ` ^"F 'Y" "8888P' `"888*"" R888" ` ^"F 'Y"
"P' "" "" "P' "" ""
""" """
DOT_CDIST = ".cdist" DOT_CDIST = ".cdist"
REMOTE_COPY = "scp -o User=root -q"
REMOTE_EXEC = "ssh -o User=root -q"
class Error(Exception): class Error(Exception):
"""Base exception class for this project""" """Base exception class for this project"""
pass pass
class UnresolvableRequirementsError(cdist.Error):
"""Resolving requirements failed"""
pass
class CdistObjectError(Error): class CdistObjectError(Error):
"""Something went wrong with an object""" """Something went wrong with an object"""

View file

@ -20,6 +20,6 @@
# #
# #
if command -v hostname; then if command -v hostname >/dev/null; then
hostname hostname -f
fi fi

View file

@ -88,6 +88,11 @@ if [ -f /etc/SuSE-release ]; then
exit 0 exit 0
fi fi
if [ -f /etc/slackware-version ]; then
echo slackware
exit 0
fi
uname_s="$(uname -s)" uname_s="$(uname -s)"
# Assume there is no tr on the client -> do lower case ourselves # Assume there is no tr on the client -> do lower case ourselves

View file

@ -54,6 +54,9 @@ case "$($__explorer/os)" in
redhat|centos) redhat|centos)
cat /etc/redhat-release cat /etc/redhat-release
;; ;;
slackware)
cat /etc/slackware-version
;;
suse) suse)
cat /etc/SuSE-release cat /etc/SuSE-release
;; ;;

View file

@ -22,7 +22,7 @@ name="$__object_id"
state_should="$(cat "$__object/parameter/state")" state_should="$(cat "$__object/parameter/state")"
state_is="$(cat "$__object/explorer/state")" state_is="$(cat "$__object/explorer/state")"
if [ "$state_should" == "$state_is" ]; then if [ "$state_should" = "$state_is" ]; then
# Nothing to do, move along # Nothing to do, move along
exit 0 exit 0
fi fi

View file

@ -0,0 +1,63 @@
cdist-type__cdist(7)
====================
Nico Schottelius <nico-cdist--@--schottelius.org>
NAME
----
cdist-type__cdist - Manage cdist installations
DESCRIPTION
-----------
This cdist type allows you to easily setup cdist
on another box, to allow the other box to configure
systems.
This type is *NOT* required by target hosts.
It is only helpful to build FROM which you configure
other hosts.
This type will use git to clone
REQUIRED PARAMETERS
-------------------
OPTIONAL PARAMETERS
-------------------
username::
Select the user to create for the cdist installation.
Defaults to "cdist".
source::
Select the source from which to clone cdist from.
Defaults to "git://github.com/telmich/cdist.git".
branch::
Select the branch to checkout from.
Defaults to "master".
EXAMPLES
--------
--------------------------------------------------------------------------------
# Install cdist for user cdist in her home as subfolder cdist
__cdist /home/cdist/cdist
# Use alternative source
__cdist --source "git://git.schottelius.org/cdist" /home/cdist/cdist
--------------------------------------------------------------------------------
SEE ALSO
--------
- cdist-type(7)
COPYING
-------
Copyright \(C) 2013 Nico Schottelius. Free use of this software is
granted under the terms of the GNU General Public License version 3 (GPLv3).

View file

@ -0,0 +1,59 @@
#!/bin/sh
#
# 2013 Nico Schottelius (nico-cdist at schottelius.org)
#
# This file is part of cdist.
#
# cdist is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# cdist is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with cdist. If not, see <http://www.gnu.org/licenses/>.
#
#
directory="$__object_id"
if [ -f "$__object/parameter/shell" ]; then
shell="--shell $(cat "$__object/parameter/shell")"
else
shell=""
fi
if [ -f "$__object/parameter/username" ]; then
username="$(cat "$__object/parameter/username")"
else
username="cdist"
fi
if [ -f "$__object/parameter/branch" ]; then
branch="$(cat "$__object/parameter/branch")"
else
branch="master"
fi
if [ -f "$__object/parameter/source" ]; then
source="$(cat "$__object/parameter/source")"
else
source="git://github.com/telmich/cdist.git"
fi
# Currently hardcoded - if anyone cares, make a parameter
# out of it
home=/home/$username
__user "$username" --home "$home" $shell
require="__user/$username" __directory "$home" \
--owner "$username"
require="__user/$username __directory/$home" __git "$directory" \
--source "$source" \
--owner "$username" --branch "$branch"

View file

@ -0,0 +1,4 @@
branch
source
username
shell

View file

@ -1,6 +1,7 @@
#!/bin/sh #!/bin/sh
# #
# 2011 Steven Armstrong (steven-cdist at armstrong.cc) # 2011-2013 Steven Armstrong (steven-cdist at armstrong.cc)
# 2013 Nico Schottelius (nico-cdist at schottelius.org)
# #
# This file is part of cdist. # This file is part of cdist.
# #
@ -18,22 +19,7 @@
# along with cdist. If not, see <http://www.gnu.org/licenses/>. # along with cdist. If not, see <http://www.gnu.org/licenses/>.
# #
name="$__object_id" name="$__object_name"
user="$(cat "$__object/parameter/user")" user="$(cat "$__object/parameter/user")"
prefix="#cdist:__cron/$name" crontab -u $user -l 2>/dev/null | grep "# $name\$" || true
suffix="#/cdist:__cron/$name"
crontab -u $user -l 2>/dev/null | awk -v prefix="$prefix" -v suffix="$suffix" '
{
if (index($0,prefix)) {
triggered=1
}
if (triggered) {
if (index($0,suffix)) {
triggered=0
}
print
}
}
'

View file

@ -1,6 +1,7 @@
#!/bin/sh #!/bin/sh
# #
# 2011 Steven Armstrong (steven-cdist at armstrong.cc) # 2011 Steven Armstrong (steven-cdist at armstrong.cc)
# 2013 Nico Schottelius (nico-cdist at schottelius.org)
# #
# This file is part of cdist. # This file is part of cdist.
# #
@ -18,39 +19,43 @@
# along with cdist. If not, see <http://www.gnu.org/licenses/>. # along with cdist. If not, see <http://www.gnu.org/licenses/>.
# #
os="$(cat "$__global/explorer/os")" name="$__object_name"
user="$(cat "$__object/parameter/user")" user="$(cat "$__object/parameter/user")"
state_should="$(cat "$__object/parameter/state")" command="$(cat "$__object/parameter/command")"
state_is=$(diff -q "$__object/parameter/entry" "$__object/explorer/entry" \
&& echo present \
|| echo absent
)
# FreeBSD mktemp doesn't allow execution without at least one param if [ -f "$__object/parameter/raw" ]; then
if [ "$os" = "freebsd" ]; then raw="$(cat "$__object/parameter/raw")"
mktemp="mktemp -t tmp" entry="$raw $command"
else else
mktemp="mktemp" minute="$(cat "$__object/parameter/minute" 2>/dev/null || echo "*")"
hour="$(cat "$__object/parameter/hour" 2>/dev/null || echo "*")"
day_of_month="$(cat "$__object/parameter/day_of_month" 2>/dev/null || echo "*")"
month="$(cat "$__object/parameter/month" 2>/dev/null || echo "*")"
day_of_week="$(cat "$__object/parameter/day_of_week" 2>/dev/null || echo "*")"
entry="$minute $hour $day_of_month $month $day_of_week $command"
fi fi
if [ "$state_is" != "$state_should" ]; then entry="$entry # $name"
case "$state_should" in mkdir "$__object/files"
present) echo "$entry" > "$__object/files/entry"
cat << DONE
tmp=\$($mktemp) if diff -q "$__object/files/entry" "$__object/explorer/entry" >/dev/null; then
crontab -u $user -l > \$tmp state_is=present
cat >> \$tmp << EOC else
$(cat "$__object/parameter/entry") state_is=absent
EOC fi
crontab -u $user \$tmp
rm \$tmp state_should="$(cat "$__object/parameter/state" 2>/dev/null || echo "present")"
DONE
;; [ "$state_is" = "$state_should" ] && exit 0
absent)
# defined in type manifest # If anything is going to change, ensure the old entries are
prefix="$(cat "$__object/parameter/prefix")" # not present anymore
suffix="$(cat "$__object/parameter/suffix")"
cat << DONE # These are the old markers
prefix="#cdist:__cron/$__object_id"
suffix="#/cdist:__cron/$__object_id"
cat << DONE
crontab -u $user -l | awk -v prefix="$prefix" -v suffix="$suffix" ' crontab -u $user -l | awk -v prefix="$prefix" -v suffix="$suffix" '
{ {
if (index(\$0,prefix)) { if (index(\$0,prefix)) {
@ -66,6 +71,16 @@ crontab -u $user -l | awk -v prefix="$prefix" -v suffix="$suffix" '
} }
' | crontab -u $user - ' | crontab -u $user -
DONE DONE
;;
esac case "$state_should" in
fi present)
echo "("
echo "crontab -u $user -l 2>/dev/null || true"
echo "echo '$entry'"
echo ") | crontab -u $user -"
;;
absent)
echo "( crontab -u $user -l 2>/dev/null || true ) | \\"
echo "grep -v \"# $name\\$\" | crontab -u $user -"
;;
esac

View file

@ -68,5 +68,5 @@ SEE ALSO
COPYING COPYING
------- -------
Copyright \(C) 2011 Steven Armstrong. Free use of this software is Copyright \(C) 2011-2013 Steven Armstrong. Free use of this software is
granted under the terms of the GNU General Public License version 3 (GPLv3). granted under the terms of the GNU General Public License version 3 (GPLv3).

View file

@ -1,45 +0,0 @@
#!/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/>.
#
name="$__object_id"
user="$(cat "$__object/parameter/user")"
command="$(cat "$__object/parameter/command")"
# set defaults
test -f "$__object/parameter/state" || echo "present" > "$__object/parameter/state"
if [ -f "$__object/parameter/raw" ]; then
raw="$(cat "$__object/parameter/raw")"
entry="$raw $command"
else
minute="$(cat "$__object/parameter/minute" 2>/dev/null || echo "*")"
hour="$(cat "$__object/parameter/hour" 2>/dev/null || echo "*")"
day_of_month="$(cat "$__object/parameter/day_of_month" 2>/dev/null || echo "*")"
month="$(cat "$__object/parameter/month" 2>/dev/null || echo "*")"
day_of_week="$(cat "$__object/parameter/day_of_week" 2>/dev/null || echo "*")"
entry="$minute $hour $day_of_month $month $day_of_week $command"
fi
# NOTE: if changed, also change in explorers
prefix="#cdist:__cron/$name"
suffix="#/cdist:__cron/$name"
echo "$prefix" | tee "$__object/parameter/prefix" > "$__object/parameter/entry"
echo "$entry" >> "$__object/parameter/entry"
echo "$suffix" | tee "$__object/parameter/suffix" >> "$__object/parameter/entry"

View file

@ -17,7 +17,7 @@ to setup configuration parameters.
REQUIRED PARAMETERS REQUIRED PARAMETERS
------------------- -------------------
file:: file::
If supplied, use the given filename as input for debconf-set-selections(1) Use the given filename as input for debconf-set-selections(1)
EXAMPLES EXAMPLES
@ -35,9 +35,11 @@ __debconf_set_selections nslcd --file "$__type/files/preseed/nslcd"
SEE ALSO SEE ALSO
-------- --------
- cdist-type(7) - cdist-type(7)
- cdist-type__update_alternatives(7)
- debconf-set-selections(1)
COPYING COPYING
------- -------
Copyright \(C) 2011 Nico Schottelius. Free use of this software is Copyright \(C) 2011-2013 Nico Schottelius. Free use of this software is
granted under the terms of the GNU General Public License version 3 (GPLv3). granted under the terms of the GNU General Public License version 3 (GPLv3).

View file

@ -0,0 +1,39 @@
#!/bin/sh
#
# 2011 Nico Schottelius (nico-cdist at schottelius.org)
#
# This file is part of cdist.
#
# cdist is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# cdist is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with cdist. If not, see <http://www.gnu.org/licenses/>.
#
#
# Check whether file exists or not
#
destination="/$__object_id"
os=$("$__explorer/os")
case "$os" in
"freebsd")
cmd="stat -f %Sg"
;;
*)
cmd="stat -c %G"
;;
esac
if [ -e "$destination" ]; then
$cmd "$destination"
fi

View file

@ -0,0 +1,39 @@
#!/bin/sh
#
# 2011 Nico Schottelius (nico-cdist at schottelius.org)
#
# This file is part of cdist.
#
# cdist is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# cdist is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with cdist. If not, see <http://www.gnu.org/licenses/>.
#
#
# Check whether file exists or not
#
destination="/$__object_id"
os=$("$__explorer/os")
case "$os" in
"freebsd")
cmd="stat -f %Op"
;;
*)
cmd="stat -c %a"
;;
esac
if [ -e "$destination" ]; then
$cmd "$destination"
fi

View file

@ -0,0 +1,39 @@
#!/bin/sh
#
# 2011 Nico Schottelius (nico-cdist at schottelius.org)
#
# This file is part of cdist.
#
# cdist is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# cdist is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with cdist. If not, see <http://www.gnu.org/licenses/>.
#
#
# Check whether file exists or not
#
destination="/$__object_id"
os=$("$__explorer/os")
case "$os" in
"freebsd")
cmd="stat -f %Su"
;;
*)
cmd="stat -c %U"
;;
esac
if [ -e "$destination" ]; then
$cmd "$destination"
fi

View file

@ -18,39 +18,51 @@
# along with cdist. If not, see <http://www.gnu.org/licenses/>. # along with cdist. If not, see <http://www.gnu.org/licenses/>.
# #
state_should="present"
[ -f "$__object/parameter/state" ] && state_should="$(cat "$__object/parameter/state")"
state_is="$(cat "$__object/explorer/state")"
[ "$state_should" = "$state_is" ] && exit 0
destination="/$__object_id" destination="/$__object_id"
state_is="$(cat "$__object/explorer/state")"
owner_is="$(cat "$__object/explorer/owner")"
group_is="$(cat "$__object/explorer/group")"
mode_is="$(cat "$__object/explorer/mode")"
state_should="present"
[ -f "$__object/parameter/state" ] && state_should="$(cat "$__object/parameter/state")"
mode=""
[ -f "$__object/parameter/mode" ] && mode="$(cat "$__object/parameter/mode")"
owner=""
[ -f "$__object/parameter/owner" ] && owner="$(cat "$__object/parameter/owner")"
group=""
[ -f "$__object/parameter/group" ] && group="$(cat "$__object/parameter/group")"
mkdiropt="" mkdiropt=""
[ -f "$__object/parameter/parents" ] && mkdiropt="-p" [ -f "$__object/parameter/parents" ] && mkdiropt="-p"
recursive="" recursive=""
[ -f "$__object/parameter/recursive" ] && recursive="-R" [ -f "$__object/parameter/recursive" ] && recursive="-R"
case "$state_should" in case "$state_should" in
present) present)
echo mkdir $mkdiropt \"$destination\" if [ "$state_is" != "present" ]; then
echo mkdir $mkdiropt \"$destination\"
fi
# Mode settings # Mode settings
if [ -f "$__object/parameter/mode" ]; then if [ "$mode" ] && [ "$mode_is" != "$mode" -o -n "$recursive" ]; then
echo chmod \"$(cat "$__object/parameter/mode")\" \"$destination\" echo chmod $recursive \"$mode\" \"$destination\"
fi fi
# Group # Group
if [ -f "$__object/parameter/group" ]; then if [ "$group" ] && [ "$group_is" != "$group" -o -n "$recursive" ]; then
echo chgrp $recursive \"$(cat "$__object/parameter/group")\" \"$destination\" echo chgrp $recursive \"$group\" \"$destination\"
fi fi
# Owner # Owner
if [ -f "$__object/parameter/owner" ]; then if [ "$owner" ] && [ "$owner_is" != "$owner" -o -n "$recursive" ]; then
echo chown $recursive \"$(cat "$__object/parameter/owner")\" \"$destination\" echo chown $recursive \"$owner\" \"$destination\"
fi fi
;; ;;
absent) absent)
echo rm -rf \"$destination\" if [ "$state_is" != "absent" ]; then
echo rm -rf \"$destination\"
fi
;; ;;
*) *)
echo "Unknown state: $state_should" >&2 echo "Unknown state: $state_should" >&2

View file

@ -36,7 +36,11 @@ owner::
BOOLEAN PARAMETERS BOOLEAN PARAMETERS
------------------ ------------------
parents:: parents::
Whether to create parents as well (mkdir -p behaviour) Whether to create parents as well (mkdir -p behaviour).
Warning: all intermediate directory permissions default
to whatever mkdir -p does.
Usually this means root:root, 0700.
recursive:: recursive::
If supplied the chgrp and chown call will run recursively. If supplied the chgrp and chown call will run recursively.

View file

@ -0,0 +1,5 @@
#!/bin/sh
destination="/$__object_id/.git"
stat --print "%G" ${destination} 2>/dev/null || exit 0

View file

@ -0,0 +1,5 @@
#!/bin/sh
destination="/$__object_id/.git"
stat --print "%U" ${destination} 2>/dev/null || exit 0

View file

@ -20,6 +20,9 @@
# #
state_is="$(cat "$__object/explorer/state")" state_is="$(cat "$__object/explorer/state")"
owner_is="$(cat "$__object/explorer/owner")"
group_is="$(cat "$__object/explorer/group")"
state_should=present state_should=present
[ -f "$__object/parameter/state" ] && state_should="$(cat "$__object/parameter/state")" [ -f "$__object/parameter/state" ] && state_should="$(cat "$__object/parameter/state")"
@ -30,11 +33,31 @@ source="$(cat "$__object/parameter/source")"
destination="/$__object_id" destination="/$__object_id"
[ "$state_should" = "$state_is" ] && exit 0 owner=""
[ -f "$__object/parameter/owner" ] && owner="$(cat "$__object/parameter/owner")"
group=""
[ -f "$__object/parameter/group" ] && group="$(cat "$__object/parameter/group")"
mode=""
[ -f "$__object/parameter/mode" ] && mode="$(cat "$__object/parameter/mode")"
[ "$state_should" = "$state_is" -a \
"$owner" = "$owner_is" -a \
"$group" = "$group_is" -a \
-n "$mode" ] && exit 0
case $state_should in case $state_should in
present) present)
echo git clone --quiet --branch "$branch" "$source" "$destination"
if [ "$state_should" != "$state_is" ]; then
echo git clone --quiet --branch "$branch" "$source" "$destination"
fi
if [ \( -n "$owner" -a "$owner_is" != "$owner" \) -o \
\( -n "$group" -a "$group_is" != "$group" \) ]; then
echo chown -R "${owner}:${group}" "$destination"
fi
if [ -n "$mode" ]; then
echo chmod -R "$mode" "$destination"
fi
;; ;;
# Handled in manifest # Handled in manifest
absent) absent)

View file

@ -27,6 +27,15 @@ state::
branch:: branch::
Create this branch by checking out the remote branch of this name Create this branch by checking out the remote branch of this name
group::
Group to chgrp to.
mode::
Unix permissions, suitable for chmod.
owner::
User to chown to.
EXAMPLES EXAMPLES
-------- --------

View file

@ -26,14 +26,11 @@ __package git --state present
state_should=present state_should=present
[ -f "$__object/parameter/state" ] && state_should="$(cat "$__object/parameter/state")" [ -f "$__object/parameter/state" ] && state_should="$(cat "$__object/parameter/state")"
[ -f "$__object/parameter/owner" ] && dirparams="$dirparams --owner $(cat "$__object/parameter/owner")"
[ -f "$__object/parameter/group" ] && dirparams="$dirparams --group $(cat "$__object/parameter/group")"
# Let __directory handle removal of git repos # Let __directory handle removal of git repos
case "$state_should" in case "$state_should" in
present) present)
__directory "$__object_id" --state present $dirparams --recursive :
;; ;;
absent) absent)

View file

@ -2,3 +2,4 @@ state
branch branch
group group
owner owner
mode

View file

@ -0,0 +1,48 @@
#!/bin/sh
# Nico Schottelius
# Zürisee, Mon Sep 2 18:38:27 CEST 2013
#
### BEGIN INIT INFO
# Provides: iptables
# Required-Start: $local_fs $remote_fs
# Required-Stop: $local_fs $remote_fs
# X-Start-Before: fail2ban
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Applies iptables ruleset
# Description: Applies all rules found in /etc/iptables.d
# and saves/restores previous status
### END INIT INFO
basedir=/etc/iptables.d
status="${basedir}/.pre-start"
case $1 in
start)
# Save status
iptables-save > "$status"
# Apply our ruleset
cd "$basedir"
count="$(ls -1 | wc -l)"
# Only do something if there are rules
if [ "$count" -ge 1 ]; then
for rule in *; do
echo "Applying iptables rule $rule ..."
iptables $(cat "$rule")
done
fi
;;
stop)
# Restore from status before, if there is something to restore
if [ -f "$status" ]; then
iptables-restore < "$status"
fi
;;
restart)
"$0" stop && "$0" start
;;
esac

View file

@ -0,0 +1,2 @@
# Rebuild rules - FIXME: do conditionally as soon as cdist supports it
echo /etc/init.d/iptables restart

View file

@ -0,0 +1,42 @@
cdist-type__iptables_apply(7)
=============================
Nico Schottelius <nico-cdist--@--schottelius.org>
NAME
----
cdist-type__iptables_apply - Apply the rules
DESCRIPTION
-----------
This cdist type deploys an init script that triggers
the configured rules and also re-applies them on
configuration.
REQUIRED PARAMETERS
-------------------
None
OPTIONAL PARAMETERS
-------------------
None
EXAMPLES
--------
None (__iptables_apply is used by __iptables_rule)
SEE ALSO
--------
- cdist-type(7)
- cdist-type__iptables_rule(7)
- iptables(8)
COPYING
-------
Copyright \(C) 2013 Nico Schottelius. Free use of this software is
granted under the terms of the GNU General Public License version 3 (GPLv3).

View file

@ -0,0 +1,26 @@
#
# 2013 Nico Schottelius (nico-cdist at schottelius.org)
#
# This file is part of cdist.
#
# cdist is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# cdist is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with cdist. If not, see <http://www.gnu.org/licenses/>.
#
#
__file /etc/init.d/iptables \
--source "$__type/files/init-script" \
--state present \
--mode 0755
require="__file/etc/init.d/iptables" __start_on_boot iptables

View file

@ -0,0 +1,64 @@
cdist-type__iptables_rule(7)
============================
Nico Schottelius <nico-cdist--@--schottelius.org>
NAME
----
cdist-type__iptables_rule - Deploy iptable rulesets
DESCRIPTION
-----------
This cdist type allows you to manage iptable rules
in a distribution independent manner.
REQUIRED PARAMETERS
-------------------
rule::
The rule to apply. Essentially an iptables command
line without iptables in front of it.
OPTIONAL PARAMETERS
-------------------
state::
'present' or 'absent', defaults to 'present'
EXAMPLES
--------
--------------------------------------------------------------------------------
# Deploy some policies
__iptables_rule policy-in --rule "-P INPUT DROP"
__iptables_rule policy-out --rule "-P OUTPUT ACCEPT"
__iptables_rule policy-fwd --rule "-P FORWARD DROP"
# The usual established rule
__iptables_rule established --rule "-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT"
# Some service rules
__iptables_rule http --rule "-A INPUT -p tcp --dport 80 -j ACCEPT"
__iptables_rule ssh --rule "-A INPUT -p tcp --dport 80 -j ACCEPT"
__iptables_rule https --rule "-A INPUT -p tcp --dport 443 -j ACCEPT"
# Ensure some rules are not present anymore
__iptables_rule munin --rule "-A INPUT -p tcp --dport 4949 -j ACCEPT" \
--state absent
--------------------------------------------------------------------------------
SEE ALSO
--------
- cdist-type(7)
- cdist-type__iptables_apply(7)
- iptables(8)
COPYING
-------
Copyright \(C) 2013 Nico Schottelius. Free use of this software is
granted under the terms of the GNU General Public License version 3 (GPLv3).

View file

@ -0,0 +1,46 @@
#
# 2013 Nico Schottelius (nico-cdist at schottelius.org)
#
# This file is part of cdist.
#
# cdist is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# cdist is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with cdist. If not, see <http://www.gnu.org/licenses/>.
#
#
base_dir=/etc/iptables.d
name="$__object_id"
if [ -f "$__object/parameter/state" ]; then
state="$(cat "$__object/parameter/state")"
else
state="present"
fi
################################################################################
# Basic setup
#
__directory "$base_dir" --state present
# Have apply do the real job
require="$__object_name" __iptables_apply
################################################################################
# The rule
#
require="__directory/$base_dir" __file "$base_dir/${name}" \
--source "$__object/parameter/rule" \
--state "$state"

View file

@ -0,0 +1 @@
rule

View file

@ -92,6 +92,20 @@ fi
present="$(cat "$__object/explorer/present")" present="$(cat "$__object/explorer/present")"
status="$(cat "$__object/explorer/status")" status="$(cat "$__object/explorer/status")"
# Handle ip="iface|addr, iface|addr" format
if [ $(expr "${ip}" : ".*|.*") -gt "0" ]; then
# If we have multiple IPs defined, $interface doesn't make sense because ip="iface|addr, iface|addr" implies it
interface=""
SAVE_IFS="$IFS"
IFS=", "
for cur_ip in ${ip}; do
# Just get the last IP address for SSH to listen on
mgmt_ip=$(echo "${ip}" | sed -E -e 's/^.*\|(.*)\/[0-9]+$/\1/')
done
IFS="$SAVE_IFS"
else
mgmt_ip=$(echo "${ip}" | cut '-d ' -f1)
fi
stopJail() { stopJail() {
# Check $status before issuing command # Check $status before issuing command
@ -160,10 +174,10 @@ EOF
createJail() { createJail() {
# Create the jail directory # Create the jail directory
cat <<EOF cat <<EOF
umask 022
mkdir -p ${jaildir}/${name} mkdir -p ${jaildir}/${name}
if [ ! -d "${jaildir}/base" ]; then if [ ! -d "${jaildir}/base" ]; then
mkdir "${jaildir}/base" mkdir "${jaildir}/base"
chmod 755 "${jaildir}/base"
tar -xzf "${jaildir}/jailbase.tgz" -C "${jaildir}/base" tar -xzf "${jaildir}/jailbase.tgz" -C "${jaildir}/base"
if [ ! -d "${jaildir}/base/usr/local" ]; then if [ ! -d "${jaildir}/base/usr/local" ]; then
mkdir -p "${jaildir}/base/usr/local" mkdir -p "${jaildir}/base/usr/local"
@ -250,7 +264,7 @@ if [ -n "$interface" ]; then
jail_${name}_interface="${interface}" jail_${name}_interface="${interface}"
END END
EOF EOF
else elif [ "$(expr "${ip}" : ".*|.*")" -eq "0" ]; then
cat <<EOF cat <<EOF
interface=\$(ifconfig -l | cut '-d ' -f1) interface=\$(ifconfig -l | cut '-d ' -f1)
cat >>/etc/rc.conf <<END cat >>/etc/rc.conf <<END
@ -316,8 +330,7 @@ echo syslogd_flags=\"-ss\" >>"${jaildir}/rw/${name}/etc/rc.conf"
EOF EOF
# Configure SSHd's listening address # Configure SSHd's listening address
cat <<EOF cat <<EOF
ip=\$(echo "${ip}" | cut '-d ' -f1) sed -E -i '.bak' -e "s/#?ListenAddress 0.0.0.0/ListenAddress ${mgmt_ip}/" "${jaildir}/rw/${name}/etc/ssh/sshd_config"
sed -i '.bak' "s/#ListenAddress 0.0.0.0/ListenAddress \${ip}/" "${jaildir}/rw/${name}/etc/ssh/sshd_config"
EOF EOF
} }

View file

@ -46,7 +46,8 @@ case "$state_should" in
;; ;;
wrongvalue) wrongvalue)
# change exisiting value # change exisiting value
echo "sed \"s|^$key\($delimiter\+\).*|$key\1$value|\" \"$file\" > \"$file.cdist-tmp\"" printf 'sed "s|^%s\(%s\+\).*|%s\\1%s|" "%s" > "%s.cdist-tmp"\n' \
"$key" "$delimiter" "$key" "$value" "$file" "$file"
echo "mv \"$file.cdist-tmp\" \"$file\"" echo "mv \"$file.cdist-tmp\" \"$file\""
;; ;;
*) *)

View file

@ -1,6 +1,6 @@
#!/bin/sh #!/bin/sh
# #
# 2012 Nico Schottelius (nico-cdist at schottelius.org) # 2012-2013 Nico Schottelius (nico-cdist at schottelius.org)
# #
# This file is part of cdist. # This file is part of cdist.
# #
@ -24,16 +24,18 @@ file="/$__object_id"
if [ -f "$__object/parameter/regex" ]; then if [ -f "$__object/parameter/regex" ]; then
regex=$(cat "$__object/parameter/regex") regex=$(cat "$__object/parameter/regex")
greparg=""
else else
if [ ! -f "$__object/parameter/line" ]; then if [ ! -f "$__object/parameter/line" ]; then
echo "Parameter line and regex missing - cannot explore" >&2 echo "Parameter line and regex missing - cannot explore" >&2
exit 1 exit 1
fi fi
regex="^$(cat "$__object/parameter/line")\$" regex="$(cat "$__object/parameter/line")"
greparg="-F -x"
fi fi
# Allow missing file - thus 2>/dev/null # Allow missing file - thus 2>/dev/null
if grep -q "$regex" "$file" 2>/dev/null; then if grep -q $greparg "$regex" "$file" 2>/dev/null; then
echo present echo present
else else
echo absent echo absent

View file

@ -38,7 +38,19 @@ case "$state_should" in
exit 1 exit 1
fi fi
echo "echo \"$line\" >> $file" #echo "echo \"$line\" >> $file"
#line_sanitised=$(cat "$__object/parameter/line" | sed 's/"/\"/g')
# Idea: replace ' in the string:
# '"'"'
# |------> ': end the string
# |-|---> "'": create ' in the output string
# |--> ': continue the string
#
# Replace all \ so \t and other combinations are not interpreted
#
line_sanitised=$(cat "$__object/parameter/line" | sed -e "s/'/'\"'\"'/g" -e 's/\\/\\\\/g')
echo "printf '%s\n' '$line_sanitised' >> $file"
;; ;;
absent) absent)
@ -47,13 +59,16 @@ case "$state_should" in
exit 1 exit 1
fi fi
[ "$line" ] && regex="^$line\$" greparg=""
if [ "$line" ]; then
regex="$line"
greparg="-F -x"
fi
cat << eof cat << eof
tmp=\$(mktemp) tmp=\$(mktemp)
sed '/$regex/d' "$file" > \$tmp && cat "\$tmp" > "$file" && rm -f "\$tmp" grep -v $greparg '$regex' '$file' > \$tmp && cat "\$tmp" > '$file' && rm -f "\$tmp"
eof eof
#echo "echo q | ex -c \"/${line}/d|w|q\" \"${file}\""
;; ;;
*) *)
echo "Unknown state: $state_should" >&2 echo "Unknown state: $state_should" >&2

View file

@ -32,11 +32,11 @@ regex::
given line, if the given regular expression does not match. given line, if the given regular expression does not match.
In case of absent, ensure all lines matching the In case of absent, ensure all lines matching the
regular expression are absent (cannot be combined with regular expression are absent.
the line parameter, if state is absent).
If the regular expression contains / (slashes), they need The regular expression is interpreted by grep.
to be escaped with \ (backslash): / becomes \/.
Must not be combined with line, if state is absent.
file:: file::
If supplied, use this as the destination file. If supplied, use this as the destination file.
@ -64,9 +64,10 @@ __line legacy_timezone --file /etc/rc.conf --regex 'TIMEZONE=.*' --state absent
SEE ALSO SEE ALSO
-------- --------
- cdist-type(7) - cdist-type(7)
- grep(1)
COPYING COPYING
------- -------
Copyright \(C) 2012 Nico Schottelius. Free use of this software is Copyright \(C) 2012-2013 Nico Schottelius. Free use of this software is
granted under the terms of the GNU General Public License version 3 (GPLv3). granted under the terms of the GNU General Public License version 3 (GPLv3).

View file

@ -0,0 +1,3 @@
de_CH.UTF-8 UTF-8
de_DE.UTF-8 UTF-8
en_US.UTF-8 UTF-8

View file

@ -0,0 +1,51 @@
#!/bin/sh
#
# 2013 Nico Schottelius (nico-cdist at schottelius.org)
#
# This file is part of cdist.
#
# cdist is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# cdist is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with cdist. If not, see <http://www.gnu.org/licenses/>.
#
#
# Let localedef do the magic
#
locale="$__object_id"
# Hardcoded, create a pull request with
# branching on $os in case it is at another location
alias=/usr/share/locale/locale.alias
input=$(echo "$locale" | cut -d . -f 1)
charmap=$(echo "$locale" | cut -d . -f 2)
# Adding locale? The name is de_CH.UTF-8
# Removing locale? The name is de_CH.utf8.
# W-T-F!
locale_remove=$(echo "$locale" | sed 's/UTF-8/utf8/')
state=$(cat "$__object/parameter/state")
case "$state" in
present)
echo localedef -A "$alias" -f "$charmap" -i "$input" "$locale"
;;
absent)
echo localedef --delete-from-archive "$locale_remove"
;;
*)
echo "Unsupported state: $state" >&2
exit 1
;;
esac

View file

@ -0,0 +1,47 @@
cdist-type__locale(7)
=====================
Nico Schottelius <nico-cdist--@--schottelius.org>
NAME
----
cdist-type__locale - Configure locales
DESCRIPTION
-----------
This cdist type allows you to setup locales.
OPTIONAL PARAMETERS
-------------------
state::
'present' or 'absent'
EXAMPLES
--------
--------------------------------------------------------------------------------
# Add locale de_CH.UTF-8
__locale de_CH.UTF-8
# Same as above, but more explicit
__locale de_CH.UTF-8 --state present
# Remove colourful British English
__locale en_GB.UTF-8 --state absent
--------------------------------------------------------------------------------
SEE ALSO
--------
- locale(1)
- localedef(1)
- cdist-type(7)
COPYING
-------
Copyright \(C) 2013 Nico Schottelius. Free use of this software is
granted under the terms of the GNU General Public License version 3 (GPLv3).

View file

@ -0,0 +1,32 @@
#!/bin/sh
#
# 2013 Nico Schottelius (nico-cdist at schottelius.org)
#
# This file is part of cdist.
#
# cdist is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# cdist is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with cdist. If not, see <http://www.gnu.org/licenses/>.
#
#
# Install required packages
#
os=$(cat "$__global/explorer/os")
case "$os" in
debian)
# Debian needs a seperate package
__package locales --state present
;;
esac

View file

@ -0,0 +1 @@
present

View file

@ -0,0 +1,33 @@
# 2013 Nico Schottelius (nico-cdist at schottelius.org)
#
# This file is part of cdist.
#
# cdist is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# cdist is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with cdist. If not, see <http://www.gnu.org/licenses/>.
#
#
os=$(cat "$__global/explorer/os")
case "$os" in
debian|ubuntu)
# Debian and Ubuntu need to be updated,
# as seen in /etc/init.d/bootlogs
echo "uname -snrvm > /var/run/motd"
echo "cat /etc/motd.tail >> /var/run/motd"
;;
*)
exit 0
;;
esac

View file

@ -42,7 +42,7 @@ case "$state_is" in
;; ;;
esac esac
aptget="DEBIAN_FRONTEND=noninteractive apt-get --quiet --yes" aptget="DEBIAN_FRONTEND=noninteractive apt-get --quiet --yes --no-install-recommends -o DPkg::Options::=\"--force-confold\""
[ "$state_is" = "$state_should" ] && exit 0 [ "$state_is" = "$state_should" ] && exit 0

View file

@ -1,6 +1,6 @@
#!/bin/sh #!/bin/sh
# #
# 2011 Nico Schottelius (nico-cdist at schottelius.org) # 2011,2013 Nico Schottelius (nico-cdist at schottelius.org)
# 2012 Giel van Schijndel (giel plus cdist at mortis dot eu) # 2012 Giel van Schijndel (giel plus cdist at mortis dot eu)
# #
# This file is part of cdist. # This file is part of cdist.
@ -42,20 +42,20 @@ case "$state_is" in
;; ;;
esac esac
if [ "$state_is" != "$state_should" ]; then [ "$state_is" = "$state_should" ] && exit 0
case "$state_should" in
present) case "$state_should" in
if [ "$present" = "notpresent" ]; then present)
if [ "$present" = "notpresent" ]; then
echo opkg --verbosity=0 update echo opkg --verbosity=0 update
fi fi
echo opkg --verbosity=0 install \"$name\" echo opkg --verbosity=0 install \"$name\"
;; ;;
absent) absent)
echo opkg --verbosity=0 remove \"$name\" echo opkg --verbosity=0 remove \"$name\"
;; ;;
*) *)
echo "Unknown state: $state" >&2 echo "Unknown state: $state" >&2
exit 1 exit 1
;; ;;
esac esac
fi

View file

@ -0,0 +1,42 @@
cdist-type__postfix(7)
======================
Steven Armstrong <steven-cdist--@--armstrong.cc>
NAME
----
cdist-type__postfix - install postfix
DESCRIPTION
-----------
This space intentionally left blank.
REQUIRED PARAMETERS
-------------------
None.
OPTIONAL PARAMETERS
-------------------
None.
EXAMPLES
--------
--------------------------------------------------------------------------------
__postfix
--------------------------------------------------------------------------------
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,33 @@
#!/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/>.
#
os=$(cat "$__global/explorer/os")
case "$os" in
ubuntu|debian|archlinux)
__package postfix --state present
;;
*)
echo "Your operating system ($os) is currently not supported by this type (${__type##*/})." >&2
echo "Please contribute an implementation for it if you can." >&2
exit 1
;;
esac

View file

@ -0,0 +1,39 @@
#!/bin/sh
#
# 2011 - 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/>.
#
config="/etc/postfix/master.cf"
# no master.cf, nothing we could do
[ -f "$config" ] || 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
}
}' "$config"

View file

@ -0,0 +1,78 @@
#!/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/>.
#
config="/etc/postfix/master.cf"
entry="$__object/files/entry"
state_should="$(cat "$__object/parameter/state")"
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
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 ${config}.cdist.XXXXXXXXXX)
# preserve ownership and permissions of existing file
cp -p "$config" "\$tmpfile"
awk -v prefix="$prefix" -v suffix="$suffix" '
{
if (index(\$0,prefix)) {
triggered=1
}
if (triggered) {
if (index(\$0,suffix)) {
triggered=0
}
} else {
print
}
}' "$config" > "\$tmpfile"
mv -f "\$tmpfile" "$config"
DONE
}
case "$state_should" in
present)
if [ "$state_is" = "changed" ]; then
remove_entry
fi
cat << DONE
cat >> "$config" << ${__type##*/}_DONE
$(cat "$entry")
${__type##*/}_DONE
DONE
;;
absent)
remove_entry
;;
esac

View file

@ -0,0 +1,73 @@
cdist-type__postfix_master(7)
=============================
Steven Armstrong <steven-cdist--@--armstrong.cc>
NAME
----
cdist-type__postfix_master - configure postfix master.cf
DESCRIPTION
-----------
See master(5) for more information.
REQUIRED PARAMETERS
-------------------
type::
See master(5)
command::
See master(5)
BOOLEAN PARAMETERS
------------------
noreload::
don't reload postfix after changes
OPTIONAL PARAMETERS
-------------------
state::
present or absent, defaults to present
service::
private::
unpriv::
chroot::
wakeup::
maxproc::
option::
Pass an option to a service. Same as using -o in master.cf.
Can be specified multiple times.
comment::
a textual comment to add with the master.cf entry
EXAMPLES
--------
--------------------------------------------------------------------------------
__postfix_master smtp --type inet --command smtpd
__postfix_master smtp --type inet --chroot y --command smtpd \
--option smtpd_enforce_tls=yes \
--option smtpd_sasl_auth_enable=yes \
--option smtpd_client_restrictions=permit_sasl_authenticated,reject
__postfix_master submission --type inet --command smtpd \
--comment "Run alternative smtp on submission port"
--------------------------------------------------------------------------------
SEE ALSO
--------
- cdist-type(7)
- master(5)
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,81 @@
#!/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/>.
#
os=$(cat "$__global/explorer/os")
case "$os" in
ubuntu|debian|archlinux)
:
;;
*)
echo "Your operating system ($os) is currently not supported by this type (${__type##*/})." >&2
echo "Please contribute an implementation for it if you can." >&2
exit 1
;;
esac
# Default to object_id
service="$(cat "$__object/parameter/service" 2>/dev/null || echo "$__object_id")"
state="$(cat "$__object/parameter/state")"
# NOTE: keep variables in sync in manifest,explorer,gencode-*
prefix="#cdist:$__object_name"
suffix="#/cdist:$__object_name"
# Generate entry for inclusion in master.cf
mkdir "$__object/files"
entry="$__object/files/entry"
(
echo "$prefix"
if [ -f "$__object/parameter/comment" ]; then
echo "# $(cat "$__object/parameter/comment")"
fi
printf "%s " "$service"
printf "%s " "$type"
for parameter in type private unpriv chroot wakeup maxproc; do
printf "%s " "$(cat "$__object/parameter/$parameter")"
done
command="$(cat "$__object/parameter/command")"
# ensure we have a trailing newline
echo "$command"
options="$(cat "$__object/parameter/option" 2>/dev/null || true)"
for option in $options; do
echo " -o $option"
done
echo "$suffix"
) > "$entry"
# Reload postfix after changes
if [ ! -f "$__object/parameter/noreload" ]; then
state_should="$(cat "$__object/parameter/state")"
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
if [ "$state_is" != "$state_should" ]; then
require="$__object_name" __postfix_reload
fi
fi

View file

@ -0,0 +1 @@
noreload

View file

@ -0,0 +1 @@
-

View file

@ -0,0 +1 @@
-

View file

@ -0,0 +1 @@
-

View file

@ -0,0 +1 @@
present

View file

@ -0,0 +1 @@
-

View file

@ -0,0 +1 @@
-

View file

@ -0,0 +1,9 @@
service
private
unpriv
chroot
wakeup
maxproc
option
comment
state

View file

@ -0,0 +1,2 @@
type
command

View file

@ -0,0 +1,37 @@
#!/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/>.
#
os=$("$__explorer/os")
case "$os" in
ubuntu|debian|archlinux)
:
;;
*)
echo "Your operating system ($os) is currently not supported by this type (${__type##*/})." >&2
echo "Please contribute an implementation for it if you can." >&2
exit 1
;;
esac
key="$(cat "$__object/parameter/key" 2>/dev/null || echo "$__object_id")"
postconf -h "$key"

View file

@ -0,0 +1,60 @@
#!/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/>.
#
os=$(cat "$__global/explorer/os")
case "$os" in
ubuntu|debian|archlinux)
:
;;
*)
echo "Your operating system ($os) is currently not supported by this type (${__type##*/})." >&2
echo "Please contribute an implementation for it if you can." >&2
exit 1
;;
esac
state_should="$(cat "$__object/parameter/state")"
if [ ! -s "$__object/explorer/value" ]; then
state_is='absent'
else
state_is=$(diff -q "$__object/parameter/value" "$__object/explorer/value" >/dev/null \
&& echo present \
|| echo changed
)
fi
if [ "$state_should" = "$state_is" ]; then
# Nothing to do, move along
exit 0
fi
key="$(cat "$__object/parameter/key" 2>/dev/null || echo "$__object_id")"
value="$(cat "$__object/parameter/value")"
case "$state_should" in
absent)
# revert parameter to its default value
echo "postconf -# $key"
;;
present)
echo "postconf -e '$key=$value'"
;;
esac

View file

@ -0,0 +1,51 @@
cdist-type__postfix_postconf(7)
===============================
Steven Armstrong <steven-cdist--@--armstrong.cc>
NAME
----
cdist-type__postfix_postconf - configure postfix main.cf
DESCRIPTION
-----------
See postconf(5) for possible keys and values.
Note that this type directly runs the postconf executable.
It does not make changes to /etc/postfix/main.cf itself.
REQUIRED PARAMETERS
-------------------
value::
the value for the postfix parameter
OPTIONAL PARAMETERS
-------------------
key::
the name of the parameter. Defaults to __object_id
EXAMPLES
--------
--------------------------------------------------------------------------------
__postfix_postconf mydomain --value somedomain.com
__postfix_postconf bind-to-special-ip --key smtp_bind_address --value 127.0.0.5
--------------------------------------------------------------------------------
SEE ALSO
--------
- cdist-type(7)
- postconf(5)
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 @@
present

View file

@ -0,0 +1 @@
value

View file

@ -0,0 +1,21 @@
#!/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/>.
#
echo "postmap /$__object_id"

View file

@ -0,0 +1,42 @@
cdist-type__postfix_postmap(7)
==============================
Steven Armstrong <steven-cdist--@--armstrong.cc>
NAME
----
cdist-type__postfix_postmap - run postmap on the given file
DESCRIPTION
-----------
This space intentionally left blank.
REQUIRED PARAMETERS
-------------------
None.
OPTIONAL PARAMETERS
-------------------
None.
EXAMPLES
--------
--------------------------------------------------------------------------------
__postfix_postmap /etc/postfix/generic
--------------------------------------------------------------------------------
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,33 @@
#!/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/>.
#
os=$(cat "$__global/explorer/os")
case "$os" in
ubuntu|debian|archlinux)
echo "postfix reload"
;;
*)
echo "Your operating system ($os) is currently not supported by this type (${__type##*/})." >&2
echo "Please contribute an implementation for it if you can." >&2
exit 1
;;
esac

View file

@ -0,0 +1,42 @@
cdist-type__postfix_reload(7)
=============================
Steven Armstrong <steven-cdist--@--armstrong.cc>
NAME
----
cdist-type__postfix_reload - tell postfix to reload its configuration
DESCRIPTION
-----------
This space intentionally left blank.
REQUIRED PARAMETERS
-------------------
None.
OPTIONAL PARAMETERS
-------------------
None.
EXAMPLES
--------
--------------------------------------------------------------------------------
__postfix_reload
--------------------------------------------------------------------------------
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

@ -19,7 +19,8 @@
# #
name="$__object_id" name="$__object_id"
state_should="$(cat "$__object/parameter/state")" state_should="present"
[ -f "$__object/parameter/state" ] && state_should="$(cat "$__object/parameter/state")"
state_is="$(cat "$__object/explorer/state")" state_is="$(cat "$__object/explorer/state")"
if [ "$state_should" != "$state_is" ]; then if [ "$state_should" != "$state_is" ]; then

View file

@ -13,14 +13,11 @@ DESCRIPTION
This cdist type allows you to create or drop postgres databases. This cdist type allows you to create or drop postgres databases.
REQUIRED PARAMETERS OPTIONAL PARAMETERS
------------------- -------------------
state:: state::
either 'present' or 'absent' either 'present' or 'absent'
OPTIONAL PARAMETERS
-------------------
owner:: owner::
the role owning this database the role owning this database
@ -29,7 +26,7 @@ EXAMPLES
-------- --------
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
__postgres_database mydbname --state present --owner mydbusername __postgres_database mydbname --owner mydbusername
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------

View file

@ -1 +1,2 @@
state
owner owner

View file

@ -20,14 +20,15 @@
name="$__object_id" name="$__object_id"
state_is="$(cat "$__object/explorer/state")" state_is="$(cat "$__object/explorer/state")"
state_should="$(cat "$__object/parameter/state")" state_should="present"
[ -f "$__object/parameter/state" ] && state_should="$(cat "$__object/parameter/state")"
[ "$state_is" = "$state_should" ] && exit 0 [ "$state_is" = "$state_should" ] && exit 0
case "$state_should" in case "$state_should" in
present) present)
if [ -f "$__object/parameter/password" ]; then if [ -f "$__object/parameter/password" ]; then
password="$(cat "$__object/parameter/$parameter")" password="$(cat "$__object/parameter/password")"
fi fi
booleans="" booleans=""
for boolean in login createdb createrole superuser; do for boolean in login createdb createrole superuser; do

View file

@ -13,15 +13,12 @@ DESCRIPTION
This cdist type allows you to create or drop postgres roles. This cdist type allows you to create or drop postgres roles.
REQUIRED PARAMETERS OPTIONAL PARAMETERS
------------------- -------------------
state:: state::
Either "present" or "absent", defaults to "present" Either "present" or "absent", defaults to "present"
All other parameters map directly to the corresponding postgres createrole
OPTIONAL PARAMETERS
-------------------
All parameter map directly to the corresponding postgres createrole
parameters. parameters.
password:: password::
@ -41,13 +38,13 @@ EXAMPLES
-------- --------
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
__postgres_role myrole --state present __postgres_role myrole
__postgres_role myrole --state present --password 'secret' __postgres_role myrole --password 'secret'
__postgres_role admin --state present --password 'very-secret' --superuser __postgres_role admin --password 'very-secret' --superuser
__postgres_role dbcustomer --state present --password 'bla' --createdb __postgres_role dbcustomer --password 'bla' --createdb
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------

View file

@ -1 +1,2 @@
state
password password

View file

@ -25,7 +25,12 @@ else
name="$__object_id" name="$__object_id"
fi fi
state_should="$(cat "$__object/parameter/state")" parameter_state="$__object/parameter/state"
if [ -f "$_parameter_state" ]; then
state_should=$(cat "$__object/parameter/state")
else
state_should="present"
fi
runs="$(cat "$__object/explorer/runs")" runs="$(cat "$__object/explorer/runs")"
if [ "$runs" ]; then if [ "$runs" ]; then

View file

@ -13,14 +13,11 @@ DESCRIPTION
This cdist type allows you to define the state of a process. This cdist type allows you to define the state of a process.
REQUIRED PARAMETERS OPTIONAL PARAMETERS
------------------- -------------------
state:: state::
Either "present" or "absent", defaults to "present" Either "present" or "absent", defaults to "present"
OPTIONAL PARAMETERS
-------------------
name:: name::
Process name to match on when using pgrep -f -x. Process name to match on when using pgrep -f -x.

View file

@ -1,3 +1,4 @@
name name
stop stop
start start
state

View file

@ -1,6 +1,6 @@
#!/bin/sh #!/bin/sh
# #
# 2012 Steven Armstrong (steven-cdist at armstrong.cc) # 2012-2013 Steven Armstrong (steven-cdist at armstrong.cc)
# #
# This file is part of cdist. # This file is part of cdist.
# #
@ -24,7 +24,7 @@ if [ -f "$__object/parameter/file" ]; then
else else
home="$(cut -d':' -f 6 "$__object/explorer/passwd")" home="$(cut -d':' -f 6 "$__object/explorer/passwd")"
file="$home/.ssh/authorized_keys" file="$home/.ssh/authorized_keys"
fi fi
entry="$__object/files/entry" entry="$__object/files/entry"
if [ ! -s "$__object/explorer/entry" ]; then if [ ! -s "$__object/explorer/entry" ]; then
@ -47,7 +47,9 @@ remove_entry() {
prefix="#cdist:$__object_name" prefix="#cdist:$__object_name"
suffix="#/cdist:$__object_name" suffix="#/cdist:$__object_name"
cat << DONE cat << DONE
tmpfile=\$(mktemp) tmpfile=\$(mktemp ${file}.cdist.XXXXXXXXXX)
# preserve ownership and permissions by copying existing file over tmpfile
cp -p "$file" "\$tmpfile"
awk -v prefix="$prefix" -v suffix="$suffix" ' awk -v prefix="$prefix" -v suffix="$suffix" '
{ {
if (index(\$0,prefix)) { if (index(\$0,prefix)) {

View file

@ -19,7 +19,7 @@
# #
owner="$(cat "$__object/parameter/owner" 2>/dev/null || echo "$__object_id")" owner="$(cat "$__object/parameter/owner" 2>/dev/null || echo "$__object_id")"
state="$(cat "$__object/parameter/present" 2>/dev/null || echo "present")" state="$(cat "$__object/parameter/state" 2>/dev/null || echo "present")"
if [ -f "$__object/parameter/file" ]; then if [ -f "$__object/parameter/file" ]; then
file="$(cat "$__object/parameter/file")" file="$(cat "$__object/parameter/file")"
else else

View file

@ -1,6 +1,6 @@
#!/bin/sh #!/bin/sh
# #
# 2012 Nico Schottelius (nico-cdist at schottelius.org) # 2012-2013 Nico Schottelius (nico-cdist at schottelius.org)
# #
# This file is part of cdist. # This file is part of cdist.
# #
@ -28,20 +28,9 @@ name="$__object_id"
case "$os" in case "$os" in
archlinux) archlinux)
# convert bash array to shell state=$(systemctl is-enabled "$name" >/dev/null 2>&1 \
daemons=$(grep ^DAEMONS /etc/rc.conf | sed -e 's/^.*=(//' -e 's/)$//') && echo present \
|| echo absent)
# absent, as long as not found
state="absent"
# iterate, last one wins.
for daemon in $daemons; do
if [ "$daemon" = "$name" -o "$daemon" = "@${name}" ]; then
state="present"
elif [ "$daemon" = "!${name}" ]; then
state="absent"
fi
done
;; ;;
debian|ubuntu|openwrt) debian|ubuntu|openwrt)
@ -54,7 +43,7 @@ case "$os" in
[ "$state" ] || state="present" [ "$state" ] || state="present"
;; ;;
*) *)
echo "Unsupported os: $os" >&2 echo "Unsupported os: $os" >&2
exit 1 exit 1
;; ;;

View file

@ -1,6 +1,6 @@
#!/bin/sh #!/bin/sh
# #
# 2012 Nico Schottelius (nico-cdist at schottelius.org) # 2012-2013 Nico Schottelius (nico-cdist at schottelius.org)
# #
# This file is part of cdist. # This file is part of cdist.
# #
@ -32,8 +32,7 @@ case "$state_should" in
present) present)
case "$os" in case "$os" in
archlinux) archlinux)
echo "sed 's/^\\(DAEMONS=.*\\))/\\1 $name)/' /etc/rc.conf > /etc/rc.conf.cdist-tmp" echo "systemctl enable \"$name\""
echo "mv /etc/rc.conf.cdist-tmp /etc/rc.conf"
;; ;;
debian|ubuntu) debian|ubuntu)
echo "update-rc.d \"$name\" defaults >/dev/null" echo "update-rc.d \"$name\" defaults >/dev/null"
@ -65,10 +64,7 @@ case "$state_should" in
absent) absent)
case "$os" in case "$os" in
archlinux) archlinux)
# Replace a) at the beginning b) in the middle c) end d) only echo "systemctl disable \"$name\""
# Support @name as well...makes it more ugly, but well...
echo "sed /etc/rc.conf -e 's/^\\(DAEMONS=(\\)@\\{0,1\\}$name /\\1/' -e 's/^\\(DAEMONS=(.* \\)@\\{0,1\\}$name \\(.*\\)/\\1\\2/' -e 's/^\\(DAEMONS=(.*\\) @\\{0,1\\}$name)/\\1)/' -e 's/^\\(DAEMONS=(\\)@\\{0,1\\}$name)/\\1)/' > /etc/rc.conf.cdist-tmp"
echo "mv /etc/rc.conf.cdist-tmp /etc/rc.conf"
;; ;;
debian|ubuntu) debian|ubuntu)
echo update-rc.d -f \"$name\" remove echo update-rc.d -f \"$name\" remove

View file

@ -0,0 +1,26 @@
#!/bin/sh
#
# 2013 Nico Schottelius (nico-cdist at schottelius.org)
#
# This file is part of cdist.
#
# cdist is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# cdist is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with cdist. If not, see <http://www.gnu.org/licenses/>.
#
#
# Setup alternative - no standard way to create, always set
#
path="$(cat "$__object/parameter/path")"
name="$__object_id"
echo "update-alternatives --quiet --set '$name' '$path'"

View file

@ -0,0 +1,43 @@
cdist-type__update_alternatives(7)
==================================
Nico Schottelius <nico-cdist--@--schottelius.org>
NAME
----
cdist-type__update_alternatives - Configure alternatives
DESCRIPTION
-----------
On Debian and alike systems update-alternatives(1) can be used
to setup alternatives for various programs.
One of the most common used targets is the "editor".
REQUIRED PARAMETERS
-------------------
path::
Use this path for the given alternative
EXAMPLES
--------
--------------------------------------------------------------------------------
# Setup vim as the default editor
__update_alternatives editor --path /usr/bin/vim.basic
--------------------------------------------------------------------------------
SEE ALSO
--------
- cdist-type(7)
- cdist-type__debconf_set_selections(7)
- update-alternatives(8)
COPYING
-------
Copyright \(C) 2013 Nico Schottelius. Free use of this software is
granted under the terms of the GNU General Public License version 3 (GPLv3).

View file

@ -0,0 +1 @@
path

View file

@ -39,6 +39,7 @@ shorten_property() {
password) ret="-p";; password) ret="-p";;
shell) ret="-s";; shell) ret="-s";;
uid) ret="-u";; uid) ret="-u";;
create-home) ret="-m";;
esac esac
echo "$ret" echo "$ret"
} }
@ -76,6 +77,7 @@ if grep -q "^${name}:" "$__object/explorer/passwd"; then
home) field=6 ;; home) field=6 ;;
shell) field=7 ;; shell) field=7 ;;
uid) field=3 ;; uid) field=3 ;;
create-home) continue;; # Does not apply to user modification
esac esac
# If we haven't already set $current_value above, pull it from the # If we haven't already set $current_value above, pull it from the
@ -102,7 +104,11 @@ if grep -q "^${name}:" "$__object/explorer/passwd"; then
else else
for property in $(ls .); do for property in $(ls .); do
new_value="$(cat "$property")" new_value="$(cat "$property")"
set -- "$@" "$(shorten_property $property)" \'$new_value\' if [ -z "$new_value" ];then # Boolean values have no value
set -- "$@" "$(shorten_property $property)"
else
set -- "$@" "$(shorten_property $property)" \'$new_value\'
fi
done done
if [ "$os" = "freebsd" ]; then if [ "$os" = "freebsd" ]; then

View file

@ -0,0 +1 @@
create-home

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# #
# 2010-2011 Nico Schottelius (nico-cdist at schottelius.org) # 2010-2013 Nico Schottelius (nico-cdist at schottelius.org)
# #
# This file is part of cdist. # This file is part of cdist.
# #
@ -20,7 +20,252 @@
# #
# #
import cdist.config_install import logging
import os
import shutil
import sys
import time
import pprint
class Config(cdist.config_install.ConfigInstall): import cdist
pass
import cdist.exec.local
import cdist.exec.remote
from cdist import core
class Config(object):
"""Cdist main class to hold arbitrary data"""
def __init__(self, local, remote, dry_run=False):
self.local = local
self.remote = remote
self.log = logging.getLogger(self.local.target_host)
self.dry_run = dry_run
self.explorer = core.Explorer(self.local.target_host, self.local, self.remote)
self.manifest = core.Manifest(self.local.target_host, self.local)
self.code = core.Code(self.local.target_host, self.local, self.remote)
def _init_files_dirs(self):
"""Prepare files and directories for the run"""
self.local.create_files_dirs()
self.remote.create_files_dirs()
@classmethod
def commandline(cls, args):
"""Configure remote system"""
import multiprocessing
# FIXME: Refactor relict - remove later
log = logging.getLogger("cdist")
initial_manifest_tempfile = None
if args.manifest == '-':
# read initial manifest from stdin
import tempfile
try:
handle, initial_manifest_temp_path = tempfile.mkstemp(prefix='cdist.stdin.')
with os.fdopen(handle, 'w') as fd:
fd.write(sys.stdin.read())
except (IOError, OSError) as e:
raise cdist.Error("Creating tempfile for stdin data failed: %s" % e)
args.manifest = initial_manifest_temp_path
import atexit
atexit.register(lambda: os.remove(initial_manifest_temp_path))
process = {}
failed_hosts = []
time_start = time.time()
for host in args.host:
if args.parallel:
log.debug("Creating child process for %s", host)
process[host] = multiprocessing.Process(target=cls.onehost, args=(host, args, True))
process[host].start()
else:
try:
cls.onehost(host, args, parallel=False)
except cdist.Error as e:
failed_hosts.append(host)
# Catch errors in parallel mode when joining
if args.parallel:
for host in process.keys():
log.debug("Joining process %s", host)
process[host].join()
if not process[host].exitcode == 0:
failed_hosts.append(host)
time_end = time.time()
log.info("Total processing time for %s host(s): %s", len(args.host),
(time_end - time_start))
if len(failed_hosts) > 0:
raise cdist.Error("Failed to configure the following hosts: " +
" ".join(failed_hosts))
@classmethod
def onehost(cls, host, args, parallel):
"""Configure ONE system"""
log = logging.getLogger(host)
try:
local = cdist.exec.local.Local(
target_host=host,
initial_manifest=args.manifest,
base_path=args.out_path,
add_conf_dirs=args.conf_dir)
remote = cdist.exec.remote.Remote(
target_host=host,
remote_exec=args.remote_exec,
remote_copy=args.remote_copy)
c = cls(local, remote, dry_run=args.dry_run)
c.run()
except cdist.Error as e:
log.error(e)
if parallel:
# We are running in our own process here, need to sys.exit!
sys.exit(1)
else:
raise
except KeyboardInterrupt:
# Ignore in parallel mode, we are existing anyway
if parallel:
sys.exit(0)
# Pass back to controlling code in sequential mode
else:
raise
def run(self):
"""Do what is most often done: deploy & cleanup"""
start_time = time.time()
self._init_files_dirs()
self.explorer.run_global_explorers(self.local.global_explorer_out_path)
self.manifest.run_initial_manifest(self.local.initial_manifest)
self.iterate_until_finished()
self.local.save_cache()
self.log.info("Finished successful run in %s seconds", time.time() - start_time)
def object_list(self):
"""Short name for object list retrieval"""
for cdist_object in core.CdistObject.list_objects(self.local.object_path,
self.local.type_path):
yield cdist_object
def iterate_once(self):
"""
Iterate over the objects once - helper method for
iterate_until_finished
"""
objects_changed = False
for cdist_object in self.object_list():
if cdist_object.requirements_unfinished(cdist_object.requirements):
"""We cannot do anything for this poor object"""
continue
if cdist_object.state == core.CdistObject.STATE_UNDEF:
"""Prepare the virgin object"""
self.object_prepare(cdist_object)
objects_changed = True
if cdist_object.requirements_unfinished(cdist_object.autorequire):
"""The previous step created objects we depend on - wait for them"""
continue
if cdist_object.state == core.CdistObject.STATE_PREPARED:
self.object_run(cdist_object)
objects_changed = True
return objects_changed
def iterate_until_finished(self):
"""
Go through all objects and solve them
one after another
"""
objects_changed = True
while objects_changed:
objects_changed = self.iterate_once()
# Check whether all objects have been finished
unfinished_objects = []
for cdist_object in self.object_list():
if not cdist_object.state == cdist_object.STATE_DONE:
unfinished_objects.append(cdist_object)
if unfinished_objects:
info_string = []
for cdist_object in unfinished_objects:
requirement_names = []
autorequire_names = []
for requirement in cdist_object.requirements_unfinished(cdist_object.requirements):
requirement_names.append(requirement.name)
for requirement in cdist_object.requirements_unfinished(cdist_object.autorequire):
autorequire_names.append(requirement.name)
requirements = ", ".join(requirement_names)
autorequire = ", ".join(autorequire_names)
info_string.append("%s requires: %s autorequires: %s" % (cdist_object.name, requirements, autorequire))
raise cdist.UnresolvableRequirementsError("The requirements of the following objects could not be resolved: %s" %
("; ".join(info_string)))
def object_prepare(self, cdist_object):
"""Prepare object: Run type explorer + manifest"""
self.log.info("Running manifest and explorers for " + cdist_object.name)
self.explorer.run_type_explorers(cdist_object)
self.manifest.run_type_manifest(cdist_object)
cdist_object.state = core.CdistObject.STATE_PREPARED
def object_run(self, cdist_object):
"""Run gencode and code for an object"""
self.log.debug("Trying to run object %s" % (cdist_object.name))
if cdist_object.state == core.CdistObject.STATE_DONE:
raise cdist.Error("Attempting to run an already finished object: %s", cdist_object)
cdist_type = cdist_object.cdist_type
# Generate
self.log.info("Generating and executing code for %s" % (cdist_object.name))
cdist_object.code_local = self.code.run_gencode_local(cdist_object)
cdist_object.code_remote = self.code.run_gencode_remote(cdist_object)
if cdist_object.code_local or cdist_object.code_remote:
cdist_object.changed = True
# Execute
if not self.dry_run:
if cdist_object.code_local:
self.code.run_code_local(cdist_object)
if cdist_object.code_remote:
self.code.transfer_code_remote(cdist_object)
self.code.run_code_remote(cdist_object)
else:
self.log.info("Skipping code execution due to DRY RUN")
# Mark this object as done
self.log.debug("Finishing run of " + cdist_object.name)
cdist_object.state = core.CdistObject.STATE_DONE

View file

@ -1,182 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# 2010-2012 Nico Schottelius (nico-cdist at schottelius.org)
#
# This file is part of cdist.
#
# cdist is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# cdist is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with cdist. If not, see <http://www.gnu.org/licenses/>.
#
#
import logging
import os
import stat
import shutil
import sys
import tempfile
import time
import itertools
import pprint
import cdist
from cdist import core
from cdist import resolver
class ConfigInstall(object):
"""Cdist main class to hold arbitrary data"""
def __init__(self, context):
self.context = context
self.log = logging.getLogger(self.context.target_host)
# Initialise local directory structure
self.context.local.create_files_dirs()
# Initialise remote directory structure
self.context.remote.create_files_dirs()
self.explorer = core.Explorer(self.context.target_host, self.context.local, self.context.remote)
self.manifest = core.Manifest(self.context.target_host, self.context.local)
self.code = core.Code(self.context.target_host, self.context.local, self.context.remote)
# Add switch to disable code execution
self.dry_run = False
def cleanup(self):
# FIXME: move to local?
destination = os.path.join(self.context.local.cache_path, self.context.target_host)
self.log.debug("Saving " + self.context.local.out_path + " to " + destination)
if os.path.exists(destination):
shutil.rmtree(destination)
shutil.move(self.context.local.out_path, destination)
def deploy_to(self):
"""Mimic the old deploy to: Deploy to one host"""
self.stage_prepare()
self.stage_run()
def deploy_and_cleanup(self):
"""Do what is most often done: deploy & cleanup"""
start_time = time.time()
self.deploy_to()
self.cleanup()
self.log.info("Finished successful run in %s seconds",
time.time() - start_time)
def stage_prepare(self):
"""Do everything for a deploy, minus the actual code stage"""
self.explorer.run_global_explorers(self.context.local.global_explorer_out_path)
self.manifest.run_initial_manifest(self.context.initial_manifest)
self.log.info("Running object manifests and type explorers")
# Continue process until no new objects are created anymore
new_objects_created = True
while new_objects_created:
new_objects_created = False
for cdist_object in core.CdistObject.list_objects(self.context.local.object_path,
self.context.local.type_path):
if cdist_object.state == core.CdistObject.STATE_PREPARED:
self.log.debug("Skipping re-prepare of object %s", cdist_object)
continue
else:
self.object_prepare(cdist_object)
new_objects_created = True
def object_prepare(self, cdist_object):
"""Prepare object: Run type explorer + manifest"""
self.log.info("Running manifest and explorers for " + cdist_object.name)
self.explorer.run_type_explorers(cdist_object)
self.manifest.run_type_manifest(cdist_object)
cdist_object.state = core.CdistObject.STATE_PREPARED
def object_run(self, cdist_object, dry_run=False):
"""Run gencode and code for an object"""
self.log.debug("Trying to run object " + cdist_object.name)
if cdist_object.state == core.CdistObject.STATE_DONE:
raise cdist.Error("Attempting to run an already finished object: %s", cdist_object)
cdist_type = cdist_object.cdist_type
# Generate
self.log.info("Generating and executing code for " + cdist_object.name)
cdist_object.code_local = self.code.run_gencode_local(cdist_object)
cdist_object.code_remote = self.code.run_gencode_remote(cdist_object)
if cdist_object.code_local or cdist_object.code_remote:
cdist_object.changed = True
# Execute
if not dry_run:
if cdist_object.code_local:
self.code.run_code_local(cdist_object)
if cdist_object.code_remote:
self.code.transfer_code_remote(cdist_object)
self.code.run_code_remote(cdist_object)
# Mark this object as done
self.log.debug("Finishing run of " + cdist_object.name)
cdist_object.state = core.CdistObject.STATE_DONE
def stage_run(self):
"""The final (and real) step of deployment"""
self.log.info("Generating and executing code")
# FIXME: think about parallel execution (same for stage_prepare)
self.all_resolved = False
while not self.all_resolved:
self.stage_run_iterate()
def stage_run_iterate(self):
"""
Run one iteration of the run
To be repeated until all objects are done
"""
objects = list(core.CdistObject.list_objects(self.context.local.object_path, self.context.local.type_path))
object_state_list=' '.join('%s:%s:%s:%s' % (o, o.state, o.all_requirements, o.satisfied_requirements) for o in objects)
self.log.debug("Object state (name:state:requirements:satisfied): %s" % object_state_list)
objects_changed = False
self.all_resolved = True
for cdist_object in objects:
if not cdist_object.state == cdist_object.STATE_DONE:
self.all_resolved = False
self.log.debug("Object %s not done" % cdist_object.name)
if cdist_object.satisfied_requirements:
self.log.debug("Running object %s with satisfied requirements" % cdist_object.name)
self.object_run(cdist_object, self.dry_run)
objects_changed = True
self.log.debug("All resolved: %s Objects changed: %s" % (self.all_resolved, objects_changed))
# Not all are resolved, but nothing has been changed => bad dependencies!
if not objects_changed and not self.all_resolved:
# Create list of unfinished objects + their requirements for print
evil_objects = []
good_objects = []
for cdist_object in objects:
if not cdist_object.state == cdist_object.STATE_DONE:
evil_objects.append("%s: required: %s, autorequired: %s" %
(cdist_object.name, cdist_object.requirements, cdist_object.autorequire))
else:
evil_objects.append("%s (%s): required: %s, autorequired: %s" %
(cdist_object.state, cdist_object.name,
cdist_object.requirements, cdist_object.autorequire))
errormessage = "Cannot solve requirements for the following objects: %s - solved: %s" % (",".join(evil_objects), ",".join(good_objects))
raise cdist.Error(errormessage)

Some files were not shown because too many files have changed in this diff Show more