Merge branch 'master' into type__git

This commit is contained in:
Nico Schottelius 2012-11-19 13:44:17 +01:00
commit 7518d527ac
559 changed files with 5289 additions and 2606 deletions

28
.gitignore vendored
View file

@ -2,17 +2,27 @@
.*.swp
# Ignore generated manpages
doc/man/.marker
doc/man/man1/*.1
doc/man/man7/*.7
doc/man/man*/*.html
doc/man/man*/*.xml
doc/man/man7/cdist-type__*.text
doc/man/man7/cdist-reference.text
doc/man/man*/docbook-xsl.css
docs/man/.marker
docs/man/man1/*.1
docs/man/man7/*.7
docs/man/man*/*.html
docs/man/man*/*.xml
docs/man/man*/docbook-xsl.css
docs/man/man7/cdist-type__*.text
docs/man/man7/cdist-reference.text
# Ignore cdist cache for version control
/cache/
# Python / cache
# Python: cache, distutils, distribution in general
__pycache__/
MANIFEST
dist/
cdist/version.py
# Packaging: Archlinux
/PKGBUILD
/cdist-*.pkg.tar.xz
/cdist-*.tar.gz
/pkg
/src

1
.version Normal file
View file

@ -0,0 +1 @@
2.1.0-pre1

3
MANIFEST.in Normal file
View file

@ -0,0 +1,3 @@
include docs/changelog
recursive-include docs/gfx *.png *.text
recursive-include docs *.text *.html *.1 *.7

23
PKGBUILD.in Executable file
View file

@ -0,0 +1,23 @@
#!/bin/sh
version=$(git describe)
outfile=${0%.in}
cat << eof > "${outfile}"
pkgname=cdist
pkgver=$version
pkgrel=1
pkgdesc='A Usable Configuration Management System"'
arch=('any')
url='http://www.nico.schottelius.org/software/cdist/'
license=('GPL3')
depends=('python>=3.2.0')
source=("http://pypi.python.org/packages/source/c/cdist/cdist-\${pkgver}.tar.gz")
package() {
cd cdist-\${pkgver}
python3 setup.py build install --root="\${pkgdir}"
}
eof
makepkg -g >> "${outfile}"

315
README
View file

@ -1,313 +1,6 @@
[[!meta title="cdist - usable configuration management"]]
.. . .x+=:. s
dF @88> z` ^% :8
'88bu. %8P . <k .88
. '*88888bu . .@8Ned8" :888ooo
.udR88N ^"*8888N .@88u .@^%8888" -*8888888
<888'888k beWE "888L ''888E` x88: `)8b. 8888
9888 'Y" 888E 888E 888E 8888N=*8888 8888
9888 888E 888E 888E %8" R88 8888
9888 888E 888F 888E @8Wou 9% .8888Lu=
?8888u../ .888N..888 888& .888888P` ^%888*
"8888P' `"888*"" R888" ` ^"F 'Y"
"P' "" ""
[[!toc levels=3]]
## Introduction
cdist is an alternative to other configuration management systems like
[cfengine](http://www.cfengine.org/),
[bcfg2](http://trac.mcs.anl.gov/projects/bcfg2),
[chef](http://wiki.opscode.com/display/chef/)
and [puppet](http://www.puppetlabs.com/).
But cdist ticks differently, here is the feature set that makes it unique:
[[!table data="""
Keywords | Description
Simplicity | There is only one type to extend cdist called ***type***
Design | Type and core cleanly seperated
Design | Sticks completly to the KISS (keep it simple and stupid) paradigma
Design | Meaningful error messages - do not lose time debugging error messages
Design | Consistency in behaviour, naming and documentation
Design | No surprise factor: Only do what is obviously clear, no magic
Design | Define target state, do not focus on methods or scripts
Design | Push architecture: Instantly apply your changes
Small core | cdist's core is very small - less code, less bugs
Fast development | Focus on straightforwardness of type creation is a main development objective
Modern Programming Language | cdist is written in Python
Requirements, Scalability | No central server needed, cdist operates in push mode and can be run from any computer
Requirements, Scalability, Upgrade | cdist only needs to be updated on the master, not on the target hosts
Requirements, Security | Uses well-know [SSH](http://www.openssh.com/) as transport protocol
Requirements, Simplicity | Requires only shell and SSH server on the target
UNIX | Reuse of existing tools like cat, find, mv, ...
UNIX, familar environment, documentation | Is available as manpages and HTML
UNIX, simplicity, familar environment | cdist is configured in POSIX shell
"""]]
### Documentation
The cdist documentation is included as manpages in the distribution.
You can browse the documentation online as well:
* [latest version](man/latest)
* [all versions (>= 2.0.4)](man)
### OS support
cdist was tested or is know to run on at least
* [Archlinux](http://www.archlinux.org/)
* [Debian](http://www.debian.org/)
* [CentOS](http://www.centos.org/)
* [Fedora](http://fedoraproject.org/)
* [Gentoo](http://www.gentoo.org/)
* [Mac OS X](http://www.apple.com/macosx/)
* [OpenBSD](http://www.openbsd.org)
* [Redhat](http://www.redhat.com/)
* [Ubuntu](http://www.ubuntu.com/)
* [XenServer](http://www.citrix.com/xenserver/)
## Requirements
### Server
* A posix like shell
* Python (>= 3.2 required)
* SSH client
* Asciidoc (for building the manpages)
### Client ("target host")
* A posix like shell
* SSH server
## Installation
### Preparation
Ensure you have Python 3.2 installed on the machine you use to **deploy to the targets**
(the ***source host***).
#### Archlinux
Archlinux already has python >= 3.2, so you only need to do:
pacman -S python
#### Debian
For Debian >= wheezy:
aptitude install python3
For older Debian versions, installing python 3.2 manually is required.
#### Fedora
For Fedora >= 15:
yum install python3
#### FreeBSD
For the port:
cd /usr/ports/lang/python32/ && make install clean
For the package:
pkg_add -r python32
#### Gentoo
Gentoo only provides python 3.2 in testing packages (http://www.gentoo.org/doc/en/handbook/handbook-x86.xml?part=3&chap=3).
If you want to ensure nothing breaks you must set back the python version to what was default before.
emerge -av =python-3.2.2 --autounmask-write
emerge -av =python-3.2.2
eselect python list
eselect python list set python3.2
#### Max OS X
You can choose between Homebrew and Macports, either way works:
[Homebrew](http://mxcl.github.com/homebrew/) variant:
brew install python3
[Macports](http://www.macports.org/install.php) variant:
port install python32
ln -s /opt/local/bin/python3.2 /opt/local/bin/python3
### Get cdist
You can clone cdist from git, which gives you the advantage of having
a version control in place for development of your own stuff as well.
To install cdist, execute the following commands:
git clone git://git.schottelius.org/cdist
cd cdist
export PATH=$PATH:$(pwd -P)/bin
# If you want the manpages
./build man
export MANPATH=$MANPATH:$(pwd -P)/doc/man
### Available versions
There are at least the following branches available:
* Development: master
* 2.0: Python rewrite of cdist core [stable branch]
Old versions:
* 1.7: Bugfixes, cleanups, new type and explorer rename
* 1.6: New types, cleaned up \_\_package* types, internal cleanup
* 1.5: Focus on object orientation instead of global stage orientation
* 1.4: Support for redefiniton of objects (if equal)
* 1.3: Support for local and remote code execution (current stable)
* 1.2: Dependencies supported
* 1.1: \_\_file to \_\_file, \_\_directory, \_\_link migration
* 1.0: First official release
Other branches may be available for features or bugfixes, but they
may vanish at any point. To select a specific branch use
# Generic code
git checkout -b <name> origin/<name>
# Stay on a specific version
version=2.0
git checkout -b $version origin/$version
### Mirrors
* git://github.com/telmich/cdist.git ([github](https://github.com/telmich/cdist))
* git://git.code.sf.net/p/cdist/code ([sourceforge](https://sourceforge.net/p/cdist/code))
## Update
To upgrade cdist in the current branch use
git pull
# Also update the manpages
./build man
export MANPATH=$MANPATH:$(pwd -P)/doc/man
If you stay on a version branche (i.e. 1.0, 1.1., ...), nothing should break.
The master branch on the other hand is the development branch and may not be
working, break your setup or eat the tree in your garden.
### Upgrading from 1.7 to 2.0
* Ensure python (>= 3.2) is installed on the server
* Use "cdist config host" instead of "cdist-deploy-to host"
* Use "cdist config -p host1 host2" instead of "cdist-mass-deploy"
* Use "cdist banner" for fun
* Use **\_\_object_fq** instead of **\_\_self** in manifests
### Upgrading from 1.6 to 1.7
* If you used the global explorer **hardware_type**, you need to change
your code to use **machine** instead.
### Upgrading from 1.5 to 1.6
* If you used **\_\_package_apt --preseed**, you need to use the new
type **\_\_debconf_set_selections** instead.
* The **\_\_package** types accepted either --state deinstalled or
--state uninstaaled. Starting with 1.6, it was made consistently
to --state removed.
### Upgrading from 1.3 to 1.5
No incompatiblities.
### Upgrading from 1.2 to 1.3
Rename **gencode** of every type to **gencode-remote**.
### Upgrading from 1.1 to 1.2
No incompatiblities.
### Upgrading from 1.0 to 1.1
In 1.1 the type **\_\_file** was split into **\_\_directory**, **\_\_file** and
**\_\_link**. The parameter **--type** was removed from **\_\_file**. Thus you
need to replace **\_\_file** calls in your manifests:
* Remove --type from all \_\_file calls
* If type was symlink, use \_\_link and --type symbolic
* If type was directory, use \_\_directory
## Support
### IRC
You can join the development ***IRC channel***
[#cstar on irc.freenode.org](irc://irc.freenode.org/#cstar).
### Mailing list
Bug reports, questions, patches, etc. should be send to the
[cdist mailing list](http://l.schottelius.org/mailman/listinfo/cdist).
### Linkedin
If you have an account
at [Linked in](http://www.linkedin.com/),
you can join the
[cdist group](http://www.linkedin.com/groups/cdist-configuration-management-3952797).
### Commercial support
You can request commercial support for cdist from
[my company](http://firma.schottelius.org/english/).
## Used by
If you're using cdist, feel free to send a report to the mailing list.
Interesting information are for instance
* Which services do you manage?
* How many machines do you manage?
* What are the pros/cons you see in cdist?
* General comments/critics
### Nico Schottelius, Systems Group ETH Zurich and privately
Yes, I'm actually eating my own dogfood and currently managing
* [plone](http://plone.org/) (cms)
* [moinmoin](http://moinmo.in/) (wiki)
* [apache](http://httpd.apache.org/) (webserver)
* [kerberos (mit)](http://web.mit.edu/kerberos/) (authentication)
* [nss-pam-ldapd](http://arthurdejong.org/nss-pam-ldapd/) (authentication)
* [ircd-hybrid](http://www.ircd-hybrid.org/) (chat)
* [stunnel](http://stunnel.mirt.net/) (SSL tunnel)
* [mercurial-server](http://www.lshift.net/mercurial-server.html) (version control)
* [xfce](http://www.xfce.org/) (lightweight desktop environment)
* [slim](http://slim.berlios.de/) (graphical login manager for X11)
with cdist on more than **60** production machines of the
[Systems Group](http://www.systems.ethz.ch) at the
[ETH Zurich](http://www.ethz.ch) as well at home.
### Steven Armstrong, CBRG ETH Zurich
The CBRG is managing most of their compute clusters with cdist.
cdist
-----
cdist is a usable configuration management system.
For the web documentation have a look at docs/web/.

221
bin/cdist
View file

@ -1,7 +1,7 @@
#!/usr/bin/env python3
#!/bin/sh
# -*- coding: utf-8 -*-
#
# 2010-2012 Nico Schottelius (nico-cdist at schottelius.org)
# 2012 Nico Schottelius (nico-cdist at schottelius.org)
#
# This file is part of cdist.
#
@ -20,215 +20,14 @@
#
#
def commandline():
"""Parse command line"""
import argparse
# Wrapper for real script to allow execution from checkout
dir=${0%/*}
import cdist.banner
import cdist.config
import cdist.install
# Ensure version is present - the bundled/shipped version contains a static version,
# the git version contains a dynamic version
"$dir/../build" version
# Construct parser others can reuse
parser = {}
# Options _all_ parsers have in common
parser['loglevel'] = argparse.ArgumentParser(add_help=False)
parser['loglevel'].add_argument('-d', '--debug',
help='Set log level to debug', action='store_true',
default=False)
parser['loglevel'].add_argument('-v', '--verbose',
help='Set log level to info, be more verbose',
action='store_true', default=False)
libdir=$(cd "${dir}/../" && pwd -P)
export PYTHONPATH="${libdir}"
# Main subcommand parser
parser['main'] = argparse.ArgumentParser(description='cdist ' + cdist.VERSION,
parents=[parser['loglevel']])
parser['main'].add_argument('-V', '--version',
help='Show version', action='version',
version='%(prog)s ' + cdist.VERSION)
parser['sub'] = parser['main'].add_subparsers(title="Commands")
# Banner
parser['banner'] = parser['sub'].add_parser('banner',
parents=[parser['loglevel']])
parser['banner'].set_defaults(func=cdist.banner.banner)
# Config and install (common stuff)
parser['configinstall'] = argparse.ArgumentParser(add_help=False)
parser['configinstall'].add_argument('host', nargs='+',
help='one or more hosts to operate on')
parser['configinstall'].add_argument('-c', '--cdist-home',
help='Change cdist home (default: .. from bin directory)',
action='store')
parser['configinstall'].add_argument('-i', '--initial-manifest',
help='Path to a cdist manifest or \'-\' to read from stdin.',
dest='manifest', required=False)
parser['configinstall'].add_argument('-p', '--parallel',
help='Operate on multiple hosts in parallel',
action='store_true', dest='parallel')
parser['configinstall'].add_argument('-s', '--sequential',
help='Operate on multiple hosts sequentially (default)',
action='store_false', dest='parallel')
# Config
parser['config'] = parser['sub'].add_parser('config',
parents=[parser['loglevel'], parser['configinstall']])
parser['config'].set_defaults(func=config)
# Install
parser['install'] = parser['sub'].add_parser('install',
parents=[parser['loglevel'], parser['configinstall']])
parser['install'].set_defaults(func=install)
for p in parser:
parser[p].epilog = "Get cdist at http://www.nico.schottelius.org/software/cdist/"
args = parser['main'].parse_args(sys.argv[1:])
# Loglevels are handled globally in here and debug wins over verbose
if args.verbose:
logging.root.setLevel(logging.INFO)
if args.debug:
logging.root.setLevel(logging.DEBUG)
log.debug(args)
args.func(args)
def config(args):
configinstall(args, mode=cdist.config.Config)
def install(args):
configinstall(args, mode=cdist.install.Install)
def configinstall(args, mode):
"""Configure or install remote system"""
import multiprocessing
import time
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=configinstall_onehost, args=(host, args, mode, True))
process[host].start()
else:
try:
configinstall_onehost(host, args, mode, 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 deploy to the following hosts: " +
" ".join(failed_hosts))
def configinstall_onehost(host, args, mode, parallel):
"""Configure or install ONE remote system"""
try:
import cdist.context
context = cdist.context.Context(
target_host=host,
initial_manifest=args.manifest,
base_path=args.cdist_home,
exec_path=sys.argv[0],
debug=args.debug)
c = mode(context)
c.deploy_and_cleanup()
context.cleanup()
except cdist.Error as e:
# We are running in our own process here, need to sys.exit!
if parallel:
log.error(e)
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 emulator():
"""Prepare and run emulator"""
import cdist.emulator
emulator = cdist.emulator.Emulator(sys.argv)
return emulator.run()
if __name__ == "__main__":
# Sys is needed for sys.exit()
import sys
exit_code = 0
try:
import logging
import os
import re
cdistpythonversion = '3.2'
if sys.version < cdistpythonversion:
raise cdist.Error('Cdist requires Python >= ' + cdistpythonversion +
' on the source host.')
# Ensure our /lib/ is included into PYTHON_PATH
sys.path.insert(0, os.path.abspath(
os.path.join(os.path.dirname(os.path.realpath(__file__)), '../lib')))
# And now import our stuff
import cdist
log = logging.getLogger("cdist")
logging.basicConfig(format='%(levelname)s: %(message)s')
if re.match("__", os.path.basename(sys.argv[0])):
emulator()
else:
commandline()
except KeyboardInterrupt:
pass
except cdist.Error as e:
log.error(e)
exit_code = 1
# Determine exit code by return value of function
sys.exit(exit_code)
"$dir/../scripts/cdist" "$@"

466
build
View file

@ -1,6 +1,6 @@
#!/bin/sh
#
# 2011 Nico Schottelius (nico-cdist at schottelius.org)
# 2011-2012 Nico Schottelius (nico-cdist at schottelius.org)
#
# This file is part of cdist.
#
@ -26,6 +26,7 @@
# exit on any error
#set -e
basedir=${0%/*}
version=$(git describe)
# Manpage and HTML
@ -33,139 +34,378 @@ A2XM="a2x -f manpage --no-xmllint -a encoding=UTF-8"
A2XH="a2x -f xhtml --no-xmllint -a encoding=UTF-8"
# Developer webbase
WEBDIR=$HOME/niconetz
WEBBASE=$WEBDIR/software/cdist
WEBDIR=$HOME/www.nico.schottelius.org
WEBBLOG=$WEBDIR/blog
WEBTOPDIR=$WEBDIR/software
WEBBASE=$WEBTOPDIR/cdist
WEBMAN=$WEBBASE/man/$version
WEBPAGE=${WEBBASE}.mdwn
# Documentation
MANDIR=doc/man
MANDIR=docs/man
MAN1DSTDIR=${MANDIR}/man1
MAN7DSTDIR=${MANDIR}/man7
SPEECHESDIR=doc/speeches
SPEECHESDIR=docs/speeches
# Change to checkout directory
cd "$basedir"
case "$1" in
man)
set -e
"$0" mangen
"$0" mantype
"$0" manbuild
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
;;
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
;;
dist-archlinux)
$0 dist-archlinux-makepkg
$0 dist-archlinux-aur-upload
;;
mantype)
for mansrc in conf/type/*/man.text; do
dst="$(echo $mansrc | sed -e 's;conf/;cdist-;' -e 's;/;;' -e 's;/man;;' -e 's;^;doc/man/man7/;')"
ln -sf "../../../$mansrc" "$dst"
done
;;
dist-archlinux-makepkg)
./PKGBUILD.in
makepkg -c --source
;;
mangen)
${MANDIR}/cdist-reference.text.sh
;;
dist-archlinux-aur-upload)
version=$($0 changelog-version)
tar=cdist-${version}-1.src.tar.gz
burp -c system "$tar"
;;
release)
./doc/dev/releasechecklist
;;
dist-freecode)
version=$($0 changelog-version)
api_token=$(awk '/machine freecode login/ { print $8 }' ~/.netrc)
speeches)
cd "$SPEECHESDIR"
for speech in *tex; do
pdflatex "$speech"
pdflatex "$speech"
pdflatex "$speech"
done
;;
webmain)
cp README ${WEBPAGE}
cd ${WEBDIR} && git commit -m "cdist main update" ${WEBPAGE}
cd ${WEBDIR} && make pub
;;
printf "Enter tag list for freecode release %s> " "$version"
read taglist
web)
cp README ${WEBPAGE}
rm -rf ${WEBMAN}
mkdir -p ${WEBMAN}/man1 ${WEBMAN}/man7
printf "Enter changelog for freecode release %s> " "$version"
read changelog
# old stuff
# rm -rf ${WEBDIR}/${WEBBASE}/speeches && mkdir ${WEBDIR}/${WEBBASE}/speeches
# cp ${SPEECHESDIR}/*.pdf ${WEBDIR}/${WEBBASE}/speeches
# git describe > ${WEBDIR}/${WEBBASE}/man/VERSION
echo "Submit preview"
cat << eof
tag_list = $taglist
changelog = $changelog
version = $version
eof
printf "Press enter to submit to freecode> "
read dummy
cp ${MAN1DSTDIR}/*.html ${MAN1DSTDIR}/*.css ${WEBMAN}/man1
cp ${MAN7DSTDIR}/*.html ${MAN7DSTDIR}/*.css ${WEBMAN}/man7
cd ${WEBDIR} && git add ${WEBBASE}
cd ${WEBDIR} && git commit -m "cdist update" ${WEBBASE} ${WEBPAGE}
cd ${WEBDIR} && make pub
cat << eof | cfreecode-api release-add cdist
{
"auth_code": "$api_token",
"release": {
"tag_list": "$taglist",
"version": "$version",
"changelog": "$changelog",
"hidden_from_frontpage": false
}
}
eof
# 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)
git push --mirror
git push --mirror github
git push --mirror sf
git push --mirror ethz
;;
dist-pypi)
$0 man
$0 version
python3 setup.py sdist upload
;;
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
;;
speeches)
cd "$SPEECHESDIR"
for speech in *tex; do
pdflatex "$speech"
pdflatex "$speech"
pdflatex "$speech"
done
;;
web)
set -e
rsync -av "${basedir}/docs/web/" "${WEBTOPDIR}"
test)
shift # skip t
export PYTHONPATH=$PYTHONPATH:$(pwd -P)/lib
cd "${WEBDIR}" && git add "${WEBBASE}"
cd "${WEBDIR}" && git commit -m "cdist update" "${WEBBASE}" "${WEBPAGE}"
cd "${WEBDIR}" && make pub
if [ $# -lt 1 ]; then
python3 -m cdist.test
else
python3 -m unittest "$@"
fi
;;
# 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 ethz; 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
;;
*)
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

@ -19,7 +19,12 @@
#
#
VERSION = "2.0.9"
import os
import subprocess
import cdist.version
VERSION = cdist.version.VERSION
BANNER = """
.. . .x+=:. s
@ -38,8 +43,6 @@ BANNER = """
DOT_CDIST = ".cdist"
import os
class Error(Exception):
"""Base exception class for this project"""
pass

View file

@ -1,6 +1,7 @@
#!/bin/sh
#
# 2010-2011 Nico Schottelius (nico-cdist at schottelius.org)
# 2012 Steven Armstrong (steven-cdist at armstrong.cc)
#
# This file is part of cdist.
#
@ -19,4 +20,6 @@
#
#
hostname
if command -v hostname; then
hostname
fi

51
cdist/conf/explorer/interfaces Executable file
View file

@ -0,0 +1,51 @@
#!/bin/sh
#
# 2012 Sébastien Gross <seb•ɑƬ•chezwam•ɖɵʈ•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/>.
#
#
# List all network interfaces in explorer/ifaces. One interface per line.
#
# If your OS is not supported please provide a ifconfig output
#
# Use ip, if available
if command -v ip; then
ip -o link show | sed -n 's/^[0-9]\+: \(.\+\): <.*/\1/p'
exit 0
fi
if ! command -v ifconfig; then
# no ifconfig, nothing we could do
exit 0
fi
uname_s="$(uname -s)"
REGEXP='s/^(.*)(:[[:space:]]*flags=|Link encap).*/\1/p'
case "$uname_s" in
Darwin)
ifconfig -a | sed -n -E "$REGEXP"
;;
Linux|*BSD)
ifconfig -a | sed -n -r "$REGEXP"
;;
*)
echo "Unsupported ifconfig output for $uname_s" >&2
exit 1
;;
esac

View file

@ -25,7 +25,7 @@ case "$($__explorer/os)" in
(. /etc/openwrt_release && echo "$DISTRIB_CODENAME")
;;
*)
lsb_release=$(which lsb_release 2>/dev/null)
lsb_release=$(command -v lsb_release)
if [ -x "$lsb_release" ]; then
$lsb_release --short --codename
fi

View file

@ -25,7 +25,7 @@ case "$($__explorer/os)" in
(. /etc/openwrt_release && echo "$DISTRIB_DESCRIPTION")
;;
*)
lsb_release=$(which lsb_release 2>/dev/null)
lsb_release=$(command -v lsb_release)
if [ -x "$lsb_release" ]; then
$lsb_release --short --description
fi

View file

@ -25,7 +25,7 @@ case "$($__explorer/os)" in
(. /etc/openwrt_release && echo "$DISTRIB_ID")
;;
*)
lsb_release=$(which lsb_release 2>/dev/null)
lsb_release=$(command -v lsb_release)
if [ -x "$lsb_release" ]; then
$lsb_release --short --id
fi

View file

@ -25,7 +25,7 @@ case "$($__explorer/os)" in
(. /etc/openwrt_release && echo "$DISTRIB_RELEASE")
;;
*)
lsb_release=$(which lsb_release 2>/dev/null)
lsb_release=$(command -v lsb_release)
if [ -x "$lsb_release" ]; then
$lsb_release --short --release
fi

View file

@ -22,4 +22,6 @@
#
#
uname -m
if command -v uname; then
uname -m
fi

View file

@ -20,7 +20,7 @@
#
set +e
executable=$(which runlevel 2>/dev/null)
executable=$(command -v runlevel)
if [ -x "$executable" ]; then
"$executable" | awk '{ print $2 }'
fi

View file

@ -0,0 +1,62 @@
## #
## # Sample manifest from cdist distribution
## #
##
## # Every machine becomes a marker, so sysadmins know that automatic
## # configurations are happening
## __file /etc/cdist-configured
## __cdistmarker
##
## case "$__target_host" in
## # Everybody has this
## localhost)
## require="__file/etc/cdist-configured" __link /tmp/cdist-testfile \
## --source /etc/cdist-configured --type symbolic
## require="__directory/tmp/cdist-test-dir" __file /tmp/cdist-test-dir/test-file \
## --mode 0750 --owner nobody --group root
## __directory /tmp/cdist-test-dir --mode 4777
##
## require="__file/etc/cdist-configured __link/tmp/cdist-testfile" \
## __file /tmp/cdist-another-testfile
##
## ;;
##
## #
## # Use an alias in /etc/hosts for localhost to use these hosts:
## #
## # 127.0.0.1 localhost.localdomain localhost cdist-archlinux
## #
## cdist-archlinux)
## # This is the specific package type for pacman
## __package_pacman zsh --state installed
##
## # The __package type autoselect the right type based on the os
## __package vim --state installed
##
## # If the type is a singleton, it does not take an object id
## __issue
## ;;
## # This is how it would look like on gentoo
## cdist-gentoo)
## # Same stuff for gentoo
## __package tree --state installed
## ;;
##
## cdist-debian)
## __package_apt atop --state installed
## __package apache2 --state removed
## ;;
##
## cdist-redhat)
## __issue
## __motd
## ;;
##
## # Real machines may be used with their hostname or fqdn,
## # depending on how you call cdist
## # ...
## # ;;
## # machine.example.org)
## # ...
## # ;;
## esac

View file

@ -26,8 +26,8 @@ name="$__object_id"
. /etc/lsb-release
repo_name="${name#ppa:}"
repo_file_name="$(echo "$repo_name" | sed "s:\/:\-:")-${DISTRIB_CODENAME}.list"
repo_file_name="$(echo "$repo_name" | sed -e "s|[/:]|-|" -e "s|\.|_|")-${DISTRIB_CODENAME}.list"
[ -s "/etc/apt/sources.list.d/${repo_file_name}" ] \
&& echo enabled || echo disabled
&& echo present || echo absent

View file

@ -22,14 +22,16 @@ name="$__object_id"
state_should="$(cat "$__object/parameter/state")"
state_is="$(cat "$__object/explorer/state")"
if [ "$state_should" != "$state_is" ]; then
case "$state_should" in
enabled)
echo add-apt-repository \"$name\"
;;
disabled)
echo remove-apt-repository \"$name\"
;;
esac
if [ "$state_should" == "$state_is" ]; then
# Nothing to do, move along
exit 0
fi
case "$state_should" in
present)
echo add-apt-repository \"$name\"
;;
absent)
echo remove-apt-repository \"$name\"
;;
esac

View file

@ -16,7 +16,7 @@ This cdist type allows manage ubuntu ppa repositories.
REQUIRED PARAMETERS
-------------------
state::
The state the ppa should be in, either "enabled" or "disabled".
The state the ppa should be in, either "present" or "absent".
OPTIONAL PARAMETERS
@ -29,10 +29,10 @@ EXAMPLES
--------------------------------------------------------------------------------
# Enable a ppa repository
__apt_ppa ppa:sans-intern/missing-bits --state enabled
__apt_ppa ppa:sans-intern/missing-bits --state present
# Disable a ppa repository
__apt_ppa ppa:sans-intern/missing-bits --state disabled
__apt_ppa ppa:sans-intern/missing-bits --state absent
--------------------------------------------------------------------------------

View file

@ -20,7 +20,7 @@
name="$__object_id"
__package python-software-properties --state installed
__package python-software-properties --state present
require="__package/python-software-properties" \
__file /usr/local/bin/remove-apt-repository \

View file

@ -20,7 +20,7 @@
# run 'apt-get update' if anything in /etc/apt is newer then /var/lib/apt/lists
cat << DONE
if find /etc/apt -cnewer /var/lib/apt/lists | grep . > /dev/null; then
if find /etc/apt -mindepth 1 -cnewer /var/lib/apt/lists | grep . > /dev/null; then
apt-get update || apt-get update
fi
DONE

View file

@ -1,6 +1,6 @@
cdist-type__cdistmarker(7)
==========================
Daniel Maher <phrawzty+cdist at gmail.com>
Daniel Maher <phrawzty+cdist--@--gmail.com>
NAME

View file

@ -24,7 +24,7 @@ user="$(cat "$__object/parameter/user")"
prefix="#cdist:__cron/$name"
suffix="#/cdist:__cron/$name"
crontab -u $user -l | awk -v prefix="$prefix" -v suffix="$suffix" '
crontab -u $user -l 2>/dev/null | awk -v prefix="$prefix" -v suffix="$suffix" '
{
if (index($0,prefix)) {
triggered=1

View file

@ -18,6 +18,7 @@
# along with cdist. If not, see <http://www.gnu.org/licenses/>.
#
os="$(cat "$__global/explorer/os")"
user="$(cat "$__object/parameter/user")"
state_should="$(cat "$__object/parameter/state")"
state_is=$(diff -q "$__object/parameter/entry" "$__object/explorer/entry" \
@ -25,14 +26,21 @@ state_is=$(diff -q "$__object/parameter/entry" "$__object/explorer/entry" \
|| echo absent
)
# FreeBSD mktemp doesn't allow execution without at least one param
if [ "$os" = "freebsd" ]; then
mktemp="mktemp -t tmp"
else
mktemp="mktemp"
fi
if [ "$state_is" != "$state_should" ]; then
case "$state_should" in
present)
cat << DONE
tmp=\$(mktemp)
tmp=\$($mktemp)
crontab -u $user -l > \$tmp
cat >> \$tmp << EOC
$(cat "$__object/parameter/entry")"
$(cat "$__object/parameter/entry")
EOC
crontab -u $user \$tmp
rm \$tmp

View file

@ -24,7 +24,7 @@
destination="/$__object_id"
if [ -e "$destination" ]; then
echo yes
echo present
else
echo no
echo absent
fi

View file

@ -0,0 +1,59 @@
#!/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/>.
#
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"
mkdiropt=""
[ -f "$__object/parameter/parents" ] && mkdiropt="-p"
recursive=""
[ -f "$__object/parameter/recursive" ] && recursive="-R"
case "$state_should" in
present)
echo mkdir $mkdiropt \"$destination\"
# Mode settings
if [ -f "$__object/parameter/mode" ]; then
echo chmod \"$(cat "$__object/parameter/mode")\" \"$destination\"
fi
# Group
if [ -f "$__object/parameter/group" ]; then
echo chgrp $recursive \"$(cat "$__object/parameter/group")\" \"$destination\"
fi
# Owner
if [ -f "$__object/parameter/owner" ]; then
echo chown $recursive \"$(cat "$__object/parameter/owner")\" \"$destination\"
fi
;;
absent)
echo rm -rf \"$destination\"
;;
*)
echo "Unknown state: $state_should" >&2
exit 1
;;
esac

View file

@ -32,13 +32,15 @@ mode::
owner::
User to chown to.
BOOLEAN PARAMETERS
------------------
parents::
Whether to create parents as well (mkdir -p behaviour). Must be yes or no.
Whether to create parents as well (mkdir -p behaviour)
recursive::
If supplied the chgrp and chown call will run recursively.
This does *not* influence the behaviour of chmod.
Must be yes or no.
EXAMPLES
@ -55,13 +57,18 @@ __directory /tmp/foobar --state absent
__directory /etc --owner root --group root --mode 0755
# Create nfs service directory, including parents
__directory /home/services/nfs --parents yes
__directory /home/services/nfs --parents
# Change permissions recursively
__directory /home/services --recursive yes --owner root --group root
__directory /home/services --recursive --owner root --group root
# Setup a temp directory
__directory /local --mode 1777
# Take it all
__directory /home/services/kvm --recursive --parents \
--owner root --group root --mode 0755 --state present
--------------------------------------------------------------------------------

View file

@ -0,0 +1,2 @@
parents
recursive

View file

@ -2,5 +2,3 @@ state
group
mode
owner
parents
recursive

View file

@ -1,6 +1,6 @@
#!/bin/sh
#
# 2011 Nico Schottelius (nico-cdist at schottelius.org)
# 2011-2012 Nico Schottelius (nico-cdist at schottelius.org)
#
# This file is part of cdist.
#
@ -24,11 +24,11 @@
destination="/$__object_id"
if [ -e "$destination" ]; then
if [ -f "$destination" ]; then
cksum < "$destination"
else
echo "NO REGULAR FILE"
fi
if [ -f "$destination" ]; then
cksum < "$destination"
else
echo "NO REGULAR FILE"
fi
else
echo "NO FILE FOUND, NO CHECKSUM CALCULATED."
echo "NO FILE FOUND, NO CHECKSUM CALCULATED."
fi

View file

@ -0,0 +1,30 @@
#!/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/>.
#
#
# Check whether file exists or not
#
destination="/$__object_id"
if [ -e "$destination" ]; then
echo yes
else
echo no
fi

View file

@ -1,6 +1,6 @@
#!/bin/sh
#
# 2011 Nico Schottelius (nico-cdist at schottelius.org)
# 2011-2012 Nico Schottelius (nico-cdist at schottelius.org)
#
# This file is part of cdist.
#
@ -22,11 +22,18 @@
#
destination="/$__object_id"
state_should="$(cat "$__object/parameter/state")"
state_should=present
[ -f "$__object/parameter/state" ] && state_should="$(cat "$__object/parameter/state")"
exists="$(cat "$__object/explorer/exists")"
if [ "$state_should" = "present" ]; then
[ "$state_should" = "exists" -a "$exists" = "yes" ] && exit 0 # nothing to do
if [ "$state_should" = "present" -o "$state_should" = "exists" ]; then
if [ -f "$__object/parameter/source" ]; then
source="$(cat "$__object/parameter/source")"
if [ "$source" = "-" ]; then
source="$__object/stdin"
fi
if [ -f "$source" ]; then
local_cksum="$(cksum < "$source")"

View file

@ -1,6 +1,6 @@
#!/bin/sh
#
# 2011 Nico Schottelius (nico-cdist at schottelius.org)
# 2011-2012 Nico Schottelius (nico-cdist at schottelius.org)
#
# This file is part of cdist.
#
@ -22,11 +22,12 @@
#
destination="/$__object_id"
state_should="$(cat "$__object/parameter/state")"
state_should=present
[ -f "$__object/parameter/state" ] && state_should="$(cat "$__object/parameter/state")"
exists="$(cat "$__object/explorer/exists")"
case "$state_should" in
present)
present|exists)
# No source? Create empty file
if [ ! -f "$__object/parameter/source" ]; then
if [ "$exists" = "no" ]; then

View file

@ -21,7 +21,11 @@ None.
OPTIONAL PARAMETERS
-------------------
state::
'present' or 'absent', defaults to 'present'
'present', 'absent' or 'exists', defaults to 'present'
where:
present: the file is exactly the one from source
absent: the file does not exist
exists: the file from source but only if it doesn't already exist
group::
Group to chgrp to.
@ -35,6 +39,7 @@ owner::
source::
If supplied, copy this file from the host running cdist to the target.
If not supplied, an empty file or directory will be created.
If source is '-' (dash), take what was written to stdin as the file content.
EXAMPLES
@ -55,6 +60,17 @@ __file /etc/issue --source "$__type/files/archlinux" --state present
__file /etc/shadow --source "$__type/files/shadow" \
--owner root --group shadow --mode 0640 \
--state present
# Provide a default file, but let the user change it
__file /home/frodo/.bashrc --source "/etc/skel/.bashrc" \
--state exists \
--owner frodo --mode 0600
# Take file content from stdin
__file /tmp/whatever --owner root --group root --mode 644 --source - << DONE
Here goes the content for /tmp/whatever
DONE
--------------------------------------------------------------------------------

View file

@ -23,6 +23,12 @@
name=$__object_id
os_version="$($__explorer/os_version)"
os="$($__explorer/os)"
if [ "$os" = "freebsd" ]; then
echo "FreeBSD does not have getent gshadow"
exit 0
fi
case "$os_version" in
"Red Hat Enterprise Linux Server release "[45]*|"CentOS release "[45]*)

View file

@ -24,6 +24,7 @@
name="$__object_id"
os_version="$(cat "$__global/explorer/os_version")"
os="$(cat "$__global/explorer/os")"
cd "$__object/parameter"
if grep -q "^${name}:" "$__object/explorer/group"; then
@ -35,7 +36,10 @@ if grep -q "^${name}:" "$__object/explorer/group"; then
case "$property" in
password)
current_value="$(awk -F: '{ print $2 }' < "$__object/explorer/gshadow")"
if [ "$os" = "freebsd" ]; then
echo "group/$name: FreeBSD doesn't support password modification" >&2
exit 1
fi
case "$os_version" in
"Red Hat Enterprise Linux Server release "[45]*|"CentOS release "[45]*)
# TODO: Use gpasswd? Need to fix gshadow explorer first.
@ -43,6 +47,7 @@ if grep -q "^${name}:" "$__object/explorer/group"; then
exit 1
;;
esac
current_value="$(awk -F: '{ print $2 }' < "$__object/explorer/gshadow")"
;;
gid)
# set to -g to support older redhat/centos
@ -57,15 +62,48 @@ if grep -q "^${name}:" "$__object/explorer/group"; then
done
if [ $# -gt 0 ]; then
echo groupmod "$@" "$name"
else
true
case $os in
freebsd)
echo pw group mod "$@" "$name"
;;
*)
echo groupmod "$@" "$name"
;;
esac
fi
else
for property in $(ls .); do
new_value="$(cat "$property")"
set -- "$@" "--$property" \"$new_value\"
if [ "$os" = "freebsd" ]; then
case $property in
gid)
proparg="-g"
;;
password)
echo "group/$name: FreeBSD doesn't support password setting" >&2
exit 1
;;
*)
# The type has been updated to support more properties than it knows how to handle for FreeBSD
# tell the user about this.
echo "Currently unknown property: $property" >&2
exit 1
;;
esac
else
proparg="--$property"
fi
set -- "$@" "$proparg" \"$new_value\"
done
echo groupadd "$@" "$name"
case $os in
freebsd)
echo pw group add "$@" "$name"
;;
*)
echo groupadd "$@" "$name"
;;
esac
fi

View file

@ -1,6 +1,6 @@
#!/bin/sh
#
# 2011 Nico Schottelius (nico-cdist at schottelius.org)
# 2011-2012 Nico Schottelius (nico-cdist at schottelius.org)
#
# This file is part of cdist.
#
@ -24,17 +24,16 @@ destination=/etc/issue
os="$(cat "$__global/explorer/os")"
if [ -f "$__object/parameter/source" ]; then
source="$(cat "$__object/parameter/source")"
echo using $source
source="$(cat "$__object/parameter/source")"
else
case "$os" in
archlinux|redhat)
source="$__type/files/$os"
;;
*)
source="$__type/files/default"
;;
esac
case "$os" in
archlinux|redhat)
source="$__type/files/$os"
;;
*)
source="$__type/files/default"
;;
esac
fi
__file "$destination" --source "$source"

1
cdist/conf/type/__jail/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
files/jailbase.tgz

View file

@ -0,0 +1,54 @@
#!/bin/sh
#
# 2012 Jake Guffey (jake.guffey at eprotex.com)
#
# This file is part of cdist.
#
# cdist is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# cdist is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with cdist. If not, see <http://www.gnu.org/licenses/>.
#
#
# See if the jailbase.tgz or $jaildir/base dir exists
#
# Debug
#exec >&2
#set -x
if [ -f "$__object/parameter/jaildir" ]; then
jaildir="$(cat "$__object/parameter/name")"
else
jaildir="/usr/jail"
fi
name="base:jailbase.tgz"
out=""
save_IFS="$IFS"
IFS=":"
for cur in $name; do
if [ -e "${jaildir}/$cur" ]; then
out="${out}:${cur}"
fi
done
IFS="$save_IFS"
if [ -z "$out" ]; then
echo "NONE"
else
echo "${out}"
fi
# Debug
#set +x

View file

@ -1,6 +1,6 @@
#!/bin/sh
#
# 2010-2011 Daniel Roth (dani-cdist@d-roth.li)
# 2012 Jake Guffey (jake.guffey at eprotex.com)
#
# This file is part of cdist.
#
@ -18,16 +18,26 @@
# along with cdist. If not, see <http://www.gnu.org/licenses/>.
#
#
# See if the requested jail exists
#
if [ -f "$__object/parameter/file" ]; then
file=$(cat "$__object/parameter/file")
# Debug
#exec >&2
#set -x
if [ -f "$__object/parameter/name" ]; then
name="$(cat "$__object/parameter/name")"
else
file="/$__object_id"
name=$__object_id
fi
result=$(cat "$__object/explorer/findline")
if [ "$result" = "NOTFOUND" ]; then
line=$(cat "$__object/parameter/line")
echo "echo $line >> $file"
if [ -f "$__object/parameter/jaildir" ]; then
jaildir="$(cat "$__object/parameter/name")"
else
jaildir="/usr/jail"
fi
[ -d "${jaildir}/$name" ] && echo "EXISTS" || echo "NOTEXIST"
#set +x

View file

@ -0,0 +1,52 @@
#!/bin/sh
#
# 2012 Jake Guffey (jake.guffey at eprotex.com)
#
# This file is part of cdist.
#
# cdist is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# cdist is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with cdist. If not, see <http://www.gnu.org/licenses/>.
#
#
# See if the requested jail is started
#
# Debug
#exec >&2
#set -x
if [ -f "$__object/parameter/name" ]; then
name="$(cat "$__object/parameter/name")"
else
name="$__object_id"
fi
if [ -f "$__object/parameter/jaildir" ]; then
jaildir="$(cat "$__object/parameter/name")"
else
jaildir="/usr/jail"
fi
# backslash-escaped $jaildir
sjaildir="$(echo ${jaildir} | sed 's#/#\\/#g')"
jls_output="$(jls | grep "[ ^I]${sjaildir}\/${name}\$")" || true
if [ -n "${jls_output}" ]; then
echo "STARTED"
else
echo "NOTSTART"
fi
# Debug
#set +x

View file

@ -0,0 +1,53 @@
#!/bin/sh
#
# 2012 Jake Guffey (jake.guffey at eprotex.com)
#
# This file is part of cdist.
#
# cdist is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# cdist is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with cdist. If not, see <http://www.gnu.org/licenses/>.
#
#
# The __jail type creates, configures, and deletes FreeBSD jails for use as
# virtual machines.
#
if [ -f "$__object/parameter/jaildir" ]; then
jaildir="$(cat "$__object/parameter/name")"
else
jaildir="/usr/jail"
fi
if [ -f "$__object/parameter/jailbase" ]; then
jailbase="$(cat "$__object/parameter/jailbase")"
else
jailbase=""
fi
state="$(cat "$__object/parameter/state")"
if [ "$state" = "present" ] && [ -z "$jailbase" ]; then
exec >&2
echo "jailbase is a REQUIRED parameter when state=present!"
exit 1
fi
remotebase="${jaildir}/jailbase.tgz"
basepresent="$(cat "$__object/explorer/basepresent")"
if [ "$state" = "present" ]; then
if [ "$basepresent" = "NONE" ]; then
echo "$__remote_copy" "${jailbase}" "$__target_host:${remotebase}"
fi # basepresent=NONE
fi # state=present

View file

@ -0,0 +1,363 @@
#!/bin/sh
#
# 2012 Jake Guffey (jake.guffey at eprotex.com)
#
# This file is part of cdist.
#
# cdist is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# cdist is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with cdist. If not, see <http://www.gnu.org/licenses/>.
#
#
# The __jail type creates, configures, and deletes FreeBSD jails for use as
# virtual machines.
#
# Debug
#exec >&2
#set -x
if [ -f "$__object/parameter/name" ]; then
name="$(cat "$__object/parameter/name")"
else
name="$__object_id"
fi
state="$(cat "$__object/parameter/state")"
if [ -f "$__object/parameter/started" ]; then
started="$(cat "$__object/parameter/started")"
else
if [ ! "$state" = "present" ]; then
started="false"
else
started="true"
fi
fi
if [ -f "$__object/parameter/ip" ]; then
ip="$(cat "$__object/parameter/ip")"
else
# IP is an optional param when $state=absent, but
# when $state=present, it's required. Enforce this.
if [ "$state" = "present" ]; then
exec >&2
echo "If --state is 'present,' --ip must be given\!"
exit 1
fi
fi
if [ -f "$__object/parameter/hostname" ]; then
hostname="$(cat "$__object/parameter/hostname")"
else
hostname="$name"
fi
if [ -f "$__object/parameter/interface" ]; then
interface="$(cat "$__object/parameter/interface")"
fi
if [ -f "$__object/parameter/devfs-enable" ]; then
devfsenable="$(cat "$__object/parameter/devfs-enable")"
else
devfsenable="true"
fi
if [ -f "$__object/parameter/devfs-ruleset" ]; then
devfsruleset="$(cat "$__object/parameter/devfs-ruleset")"
else
devfsruleset="jailrules"
fi
# devfs_ruleset being defined without devfs_enable being true
# is pointless. Treat this as an error.
if [ -n "$devfsruleset" -a "$devfsenable" = "false" ]; then
exec >&2
echo "Can't have --devfs-ruleset defined without --devfs-enable true."
exit 1
fi
if [ -f "$__object/parameter/onboot" ]; then
onboot="$(cat "$__object/parameter/onboot")"
fi
if [ -f "$__object/parameter/jaildir" ]; then
jaildir="$(cat "$__object/parameter/name")"
else
jaildir="/usr/jail"
fi
present="$(cat "$__object/explorer/present")"
status="$(cat "$__object/explorer/status")"
# Defining a jail as absent and started at the same time
# makes no sense. Treat this as an error.
if [ "$started" = "true" -a "$state" = "absent" ]; then
exec >&2
echo "Can't have --state absent and --started true together\!"
exit 1
fi
stopJail() {
# Check $status before issuing command
if [ "$status" = "STARTED" ]; then
echo "/etc/rc.d/jail stop ${name}"
fi
}
startJail() {
# Check $status before issuing command
if [ "$status" = "NOTSTART" ]; then
echo "/etc/rc.d/jail start ${name}"
fi
}
deleteJail() {
# Unmount the jail's mountpoints if necessary
cat <<EOF
output="\$(mount | grep "\/${name}\/dev")" || true
if [ -n "\${output}" ]; then # /dev is still mounted...jail still running?
/etc/rc.d/jail stop "${name}"
fi
output="\$(mount | grep "\/rw\/${name}\/")" || true
if [ -n "\${output}" ]; then # >=1 rw mount is mounted still
for DIR in "${output}"; do
umount -F "/etc/fstab.${name}" "\$(echo "${DIR}" | awk '{print $3}')"
done
fi
output="\$(mount | grep "\/${name} (")" || true
if [ -n "\${output}" ]; then # ro mount is mounted still
umount -F "/etc/fstab.${name}" "\$(echo "${output}" | awk '{print $3}')"
fi
EOF
# Remove the jail's rw mountpoints
echo "rm -rf \"${jaildir}/rw/${name}\""
# Remove the jail directory
echo "rm -rf \"${jaildir}/${name}\""
# Remove the jail's fstab
echo "rm -f \"/etc/fstab.${name}\""
# Remove jail_$name_* lines from rc.conf
cat <<EOF
sed -i '.bak' "/^jail_${name}_/d" /etc/rc.conf
if [ -f "/etc/rc.conf.bak" ]; then
rm -f /etc/rc.conf.bak
fi
EOF
# Remove " $name " from jail_list if it's there
cat <<EOF
eval \$(grep '^jail_list=' /etc/rc.conf)
for JAIL in \${jail_list}; do
if [ ! "\${JAIL}" = "${name}" ]; then
new_list="\${new_list} \${JAIL}"
fi
done
jail_list="\${new_list}"
sed -i '.bak' "s/^jail_list=\".*\"/jail_list=\"\${jail_list}\"/" /etc/rc.conf
unset jail_list
if [ -f "/etc/rc.conf.bak" ]; then
rm -f /etc/rc.conf.bak
fi
EOF
}
createJail() {
# Create the jail directory
cat <<EOF
mkdir -p ${jaildir}/${name}
if [ ! -d "${jaildir}/base" ]; then
mkdir "${jaildir}/base"
chmod 755 "${jaildir}/base"
tar -xzf "${jaildir}/jailbase.tgz" -C "${jaildir}/base"
if [ ! -d "${jaildir}/base/usr/local" ]; then
mkdir -p "${jaildir}/base/usr/local"
fi
if [ ! -d "${jaildir}/base/usr/home" ]; then
mkdir -p "${jaildir}/base/usr/home"
fi
if [ ! -d "${jaildir}/base/home" ]; then
if [ ! -L "${jaildir}/base/home" ]; then
SAVE=\$PWD; cd ${jaildir}/base
ln -s usr/home home
cd \$SAVE; unset SAVE
fi
fi
fi
if [ ! -d "${jaildir}/rw" ]; then
mkdir "${jaildir}/rw"
fi
mkdir -p "${jaildir}/rw/${name}/etc"
cp -r ${jaildir}/base/etc/* "${jaildir}/rw/${name}/etc/"
if [ ! -f "${jaildir}/rw/${name}/etc/resolv.conf" ]; then
cp /etc/resolv.conf "${jaildir}/rw/${name}/etc/"
fi
mkdir "${jaildir}/rw/${name}/local"
mkdir "${jaildir}/rw/${name}/var"
if [ -n "\$(ls ${jaildir}/base/var)" ]; then
cp -r ${jaildir}/base/var/* "${jaildir}/rw/${name}/var/"
fi
chmod 755 "${jaildir}/rw/${name}/var"
chmod 755 "${jaildir}/base/var"
if [ -n "\$(ls ${jaildir}/base/var/db)" ]; then
chmod 755 "${jaildir}/rw/${name}/var/db"
chmod 755 "${jaildir}/base/var/db"
fi
mkdir "${jaildir}/rw/${name}/home"
if [ -n "\$(ls ${jaildir}/base/usr/home)" ]; then
cp -r ${jaildir}/base/usr/home/* "${jaildir}/rw/${name}/home/"
fi
mkdir "${jaildir}/rw/${name}/root"
if [ -n "\$(ls -A ${jaildir}/base/root)" ]; then
cp -r ${jaildir}/base/root/ "${jaildir}/rw/${name}/root/"
fi
EOF
# Create the ro+rw mountpoint entries in fstab
cat <<EOF
cat >/etc/fstab.${name} <<END
${jaildir}/base ${jaildir}/${name} nullfs ro 0 0
${jaildir}/rw/${name}/etc ${jaildir}/${name}/etc nullfs rw 0 0
${jaildir}/rw/${name}/local ${jaildir}/${name}/usr/local nullfs rw 0 0
${jaildir}/rw/${name}/var ${jaildir}/${name}/var nullfs rw 0 0
${jaildir}/rw/${name}/home ${jaildir}/${name}/usr/home nullfs rw 0 0
${jaildir}/rw/${name}/root ${jaildir}/${name}/root nullfs rw 0 0
END
EOF
# Add the jail_$name_* lines to rc.conf
cat <<EOF
# first check to see whether jail_enable="YES" exists in rc.conf or not and add it
# if necessary
jail_enable="\$(grep '^jail_enable=' /etc/rc.conf | cut -d= -f2)"
if [ -z "\$jail_enable" ]; then # no jail_enable line in rc.conf at all
echo "jail_enable=\"YES\"" >>/etc/rc.conf
elif [ ! "\$(echo \$jail_enable | tr '[a-z]' '[A-Z]')" = "YES" ]; then # jail_enable="NO"
sed -i '.bak' 's/^jail_enable=.*$/jail_enable="YES"/g' /etc/rc.conf # fix this -^
rm -f /etc/rc.conf.bak
fi
cat >>/etc/rc.conf <<END
jail_${name}_rootdir="${jaildir}/${name}"
jail_${name}_hostname="${hostname}"
jail_${name}_ip="${ip}"
jail_${name}_devfs_enable="${devfsenable}"
jail_${name}_mount_enable="YES"
jail_${name}_fstab="/etc/fstab.${name}"
jail_${name}_flags="-n ${name} \\\${jail_flags}"
END
EOF
if [ -n "$interface" ]; then
cat <<EOF
cat >>/etc/rc.conf <<END
jail_${name}_interface="${interface}"
END
EOF
else
cat <<EOF
interface=\$(ifconfig -l | cut '-d ' -f1)
cat >>/etc/rc.conf <<END
jail_${name}_interface="\${interface}"
END
EOF
fi
if [ "$devfsenable" = "true" ]; then
cat <<EOF
cat >>/etc/rc.conf <<END
jail_${name}_devfs_ruleset="${devfsruleset}"
END
if [ "${devfsruleset}" = "jailrules" ]; then # The default ruleset is to be used
if [ ! -f /etc/devfs.rules ]; then
touch /etc/devfs.rules
fi
if [ -z "\$(grep '\[jailrules=' /etc/devfs.rules)" ]; then # The default ruleset doesn't exist
# Get the highest-numbered ruleset
highest="\$(sed -n 's/\[.*=\([0-9]*\)\]/\1/pg' /etc/devfs.rules | sort -u | tail -n 1)" || true
# increment by 1
let num="\${highest}+1" 2>&- >&-
# add default ruleset
cat >>/etc/devfs.rules <<END
[jailrules=\${num}]
add include \\\$devfsrules_hide_all
add include \\\$devfsrules_unhide_basic
add include \\\$devfsrules_unhide_login
END
fi
fi
EOF
fi
# Add $name to jail_list if $onboot=yes
if [ "$onboot" = "yes" ]; then
# first check to see whether jail_enable="YES" exists in rc.conf or not and add it
# if necessary
cat <<EOF
eval "\$(grep '^jail_list=' /etc/rc.conf)"
if [ -z "\$jail_list" ]; then # no jail_list line in rc.conf at all
echo "jail_list=\"${name}\"" >>/etc/rc.conf
else
jail_list="\${jail_list} ${name}"
sed -i '.bak' "s/^jail_list=\".*\"/jail_list=\"\${jail_list}\"/" /etc/rc.conf
rm -f /etc/rc.conf.bak
fi
unset jail_list
EOF
fi
# Add the normal entries into the jail's rc.conf
cat <<EOF
echo hostname=\"${hostname}\" >"${jaildir}/rw/${name}/etc/rc.conf"
echo sshd_enable=\"YES\" >>"${jaildir}/rw/${name}/etc/rc.conf"
echo sendmail_enable=\"NONE\" >>"${jaildir}/rw/${name}/etc/rc.conf"
echo syslogd_enable=\"YES\" >>"${jaildir}/rw/${name}/etc/rc.conf"
echo syslogd_flags=\"-ss\" >>"${jaildir}/rw/${name}/etc/rc.conf"
EOF
# Configure SSHd's listening address
cat <<EOF
ip=\$(echo "${ip}" | cut '-d ' -f1)
sed -i '.bak' "s/#ListenAddress 0.0.0.0/ListenAddress \${ip}/" "${jaildir}/rw/${name}/etc/ssh/sshd_config"
EOF
}
if [ "$present" = "EXISTS" ]; then # The jail currently exists
if [ "$state" = "present" ]; then # The jail is supposed to exist
if [ "$started" = "true" ]; then # The jail is supposed to be started
startJail
else # The jail is not supposed to be started
stopJail
fi
exit 0
else # The jail is not supposed to exist
stopJail
deleteJail
exit 0
fi
else # The jail does not currently exist
if [ "$state" = "absent" ]; then # The jail is not supposed to be present
exit 0
else # The jail is supposed to exist
createJail
[ "$started" = "true" ] && startJail
exit 0
fi
fi
# Debug
#set +x

View file

@ -0,0 +1,106 @@
cdist-type__jail(7)
===================
Jake Guffey <jake.guffey--@--eprotex.com>
NAME
----
cdist-type__jail - Manage FreeBSD jails
DESCRIPTION
-----------
This type is used on FreeBSD to manage jails.
REQUIRED PARAMETERS
-------------------
state::
Either "present" or "absent."
jailbase::
The location of the .tgz archive containing the base fs for your jails.
OPTIONAL PARAMETERS
-------------------
name::
The name of the jail. Default is to use the object_id as the jail name.
started::
Either "true" or "false." Defaults to true.
ip::
The ifconfig style IP/netmask combination to use for the jail guest. If
the state parameter is "present," this parameter is required.
hostname::
The FQDN to use for the jail guest. Defaults to the name parameter.
interface::
The name of the physical interface on the jail server to bind the jail to.
Defaults to the first interface found in the output of ifconfig -l.
devfs-enable::
Whether to allow devfs mounting within the jail. Must be "true" or "false."
Defaults to true.
devfs-ruleset::
The name of the devfs ruleset to associate with the jail. Defaults to
"jailrules." This ruleset must be copied to the server via another type.
To use this option, devfs-enable must be "true."
onboot::
Whether to add the jail to rc.conf's jail_list variable. Must be either
"true" or "false." Defaults to false.
jaildir::
The location on the remote server to use for hosting jail filesystems.
Defaults to /usr/jail.
CAVEATS
-------
This type does not currently support modification of jail options. If, for
example a jail needs to have its IP address or netmask changed, the jail must
be removed then re-added with the correct IP address/netmask or the appropriate
line (jail_<name>_ip="...") modified within rc.conf through some alternate
means.
EXAMPLES
--------
--------------------------------------------------------------------------------
# Create a jail called www
__jail www --state present --ip "192.168.1.2" --jailbase /my/jail/base.tgz
# Remove the jail called www
__jail www --state absent --jailbase /my/jail/base.tgz
# Ensure that the jail called www is started
__jail www --state present --started true \
--ip "192.168.1.2 netmask 255.255.255.0" \
--jailbase /my/jail/base.tgz
# Use the name variable explicitly
__jail thisjail --state present --name www \
--ip "192.168.1.2" \
--jailbase /my/jail/base.tgz
# Go nuts
__jail lotsofoptions --state present --name testjail --started true \
--ip "192.168.1.100 netmask 255.255.255.0" \
--hostname "testjail.example.com" --interface "em0" \
--onboot yes --jailbase /my/jail/base.tgz --jaildir /jails
--------------------------------------------------------------------------------
SEE ALSO
--------
- cdist-type(7)
COPYING
-------
Copyright \(C) 2012 Jake Guffey. Free use of this software is
granted under the terms of the GNU General Public License version 3 (GPLv3).

46
cdist/conf/type/__jail/manifest Executable file
View file

@ -0,0 +1,46 @@
#!/bin/sh
#
# 2012 Jake Guffey (jake.guffey at eprotex.com)
#
# This file is part of cdist.
#
# cdist is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# cdist is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with cdist. If not, see <http://www.gnu.org/licenses/>.
#
#
# The __jail type creates, configures, and deletes FreeBSD jails for use as
# virtual machines.
#
# Debug
#exec >&2
#set -x
# Can only be used on FreeBSD
os="$(cat "$__global/explorer/os")"
if [ ! "$os" = "freebsd" ]; then
echo "__jail can only be used on FreeBSD targets!" >&2
exit 1
fi
if [ -f "$__object/parameter/jaildir" ]; then
jaildir="$(cat "$__object/parameter/name")"
else
jaildir="/usr/jail"
fi
__directory ${jaildir} --parents
# Debug
#set +x

View file

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

View file

@ -0,0 +1,60 @@
#!/bin/sh
#
# 2011 Steven Armstrong (steven-cdist at armstrong.cc)
# 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/>.
#
key="$__object_id"
[ -f "$__object/parameter/key" ] && key="$(cat "$__object/parameter/key")"
state_should=present
[ -f "$__object/parameter/state" ] && state_should="$(cat "$__object/parameter/state")"
file="$(cat "$__object/parameter/file")"
delimiter="$(cat "$__object/parameter/delimiter")"
value="$(cat "$__object/parameter/value")"
state_is="$(cat "$__object/explorer/state")"
[ "$state_is" = "$state_should" ] && exit 0
case "$state_should" in
absent)
# remove lines starting with key
echo "sed '/^$key\($delimiter\+\)/d' \"$file\" > \"$file.cdist-tmp\""
echo "mv \"$file.cdist-tmp\" \"$file\""
;;
present)
case "$state_is" in
absent)
# add new key and value
echo "echo \"${key}${delimiter}${value}\" >> \"$file\""
;;
wrongvalue)
# change exisiting value
echo "sed \"s|^$key\($delimiter\+\).*|$key\1$value|\" \"$file\" > \"$file.cdist-tmp\""
echo "mv \"$file.cdist-tmp\" \"$file\""
;;
*)
echo "Unknown explorer state: $state_is" >&2
exit 1
esac
;;
*)
echo "Unknown state: $state_should" >&2
exit 1
esac

View file

@ -19,6 +19,10 @@
# along with cdist. If not, see <http://www.gnu.org/licenses/>.
#
# set default: present, if not setup
statefile="$__object/parameter/state"
[ -f "$statefile" ] || echo present > "$statefile"
state_should=present
[ -f "$__object/parameter/state" ] && state_should="$(cat "$__object/parameter/state")"
if [ "$state_should" = "present" -a ! -f "$__object/parameter/value" ]; then
echo "Missing required parameter 'value'" >&2
exit 1
fi

View file

@ -1,7 +1,6 @@
#!/bin/sh
#
# 2010-2011 Daniel Roth (dani-cdist@d-roth.li)
# 2011 Nico Schottelius (nico-cdist at schottelius.org)
# 2012 Nico Schottelius (nico-cdist at schottelius.org)
#
# This file is part of cdist.
#
@ -20,29 +19,22 @@
#
#
if [ -f "$__object/parameter/file" ]; then
file=$(cat "$__object/parameter/file")
else
file="/$__object_id"
fi
file="/$__object_id"
[ -f "$__object/parameter/file" ] && file=$(cat "$__object/parameter/file")
if [ -f "$__object/parameter/regex" ]; then
regex=$(cat "$__object/parameter/regex")
else
wrap=$(cat "$__object/parameter/line")
regex="^$wrap\$"
if [ ! -f "$__object/parameter/line" ]; then
echo "Parameter line and regex missing - cannot explore" >&2
exit 1
fi
regex="^$(cat "$__object/parameter/line")\$"
fi
if [ -f "$file" ]; then
# sh -e is our environment, we know what we do,
# skip error detection for now
set +e
grep -q "$regex" "$file"
if [ $? -eq 1 ]; then
echo "NOTFOUND"
else
echo "FOUND"
fi
# Allow missing file - thus 2>/dev/null
if grep -q "$regex" "$file" 2>/dev/null; then
echo present
else
echo "NOTFOUND"
echo absent
fi

View file

@ -0,0 +1,62 @@
#!/bin/sh
#
# 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/>.
#
#
file="/$__object_id"
regex=""
state_should="present"
[ -f "$__object/parameter/file" ] && file=$(cat "$__object/parameter/file")
[ -f "$__object/parameter/regex" ] && regex=$(cat "$__object/parameter/regex")
[ -f "$__object/parameter/state" ] && state_should=$(cat "$__object/parameter/state")
[ -f "$__object/parameter/line" ] && line=$(cat "$__object/parameter/line")
state_is="$(cat "$__object/explorer/state")"
[ "$state_should" = "$state_is" ] && exit 0
case "$state_should" in
present)
if [ ! "$line" ]; then
echo "Required parameter \"line\" is missing" >&2
exit 1
fi
echo "echo \"$line\" >> $file"
;;
absent)
if [ "$regex" -a "$line" ]; then
echo "Mutally exclusive parameters regex and line given for state absent" >&2
exit 1
fi
[ "$line" ] && regex="^$line\$"
cat << eof
tmp=\$(mktemp)
sed '/$regex/d' "$file" > \$tmp && cat "\$tmp" > "$file" && rm -f "\$tmp"
eof
#echo "echo q | ex -c \"/${line}/d|w|q\" \"${file}\""
;;
*)
echo "Unknown state: $state_should" >&2
exit 1
;;
esac

View file

@ -0,0 +1,72 @@
cdist-type__line(7)
===================
Nico Schottelius <nico-cdist--@--schottelius.org>
NAME
----
cdist-type__line - Manage lines in files
DESCRIPTION
-----------
This cdist type allows you to add lines and remove lines from files.
REQUIRED PARAMETERS
-------------------
OPTIONAL PARAMETERS
-------------------
state::
'present' or 'absent', defaults to 'present'
line::
Specifies the line which should be absent or present
Must be present, if state is present.
Must not be combined with regex, if state is absent.
regex::
If state is present, search for this pattern and add
given line, if the given regular expression does not match.
In case of absent, ensure all lines matching the
regular expression are absent (cannot be combined with
the line parameter, if state is absent).
If the regular expression contains / (slashes), they need
to be escaped with \ (backslash): / becomes \/.
file::
If supplied, use this as the destination file.
Otherwise the object_id is used.
EXAMPLES
--------
--------------------------------------------------------------------------------
# Manage the DAEMONS line in rc.conf
__line daemons --file /etc/rc.conf --line 'DAEMONS=(hwclock !network sshd crond postfix)'
# Ensure the home mount is present in /etc/fstab - explicitly make it present
__line home-fstab \
--file /etc/fstab \
--line 'filer.fs:/vol/home /home nfs defaults 0 0' \
--state present
# Removes the line specifiend in "include_www" from the file "lighttpd.conf"
__line legacy_timezone --file /etc/rc.conf --regex 'TIMEZONE=.*' --state absent
--------------------------------------------------------------------------------
SEE ALSO
--------
- cdist-type(7)
COPYING
-------
Copyright \(C) 2012 Nico Schottelius. Free use of this software is
granted under the terms of the GNU General Public License version 3 (GPLv3).

View file

@ -1,6 +1,6 @@
#!/bin/sh
#
# 2011 Nico Schottelius (nico-cdist at schottelius.org)
# 2011-2012 Nico Schottelius (nico-cdist at schottelius.org)
#
# This file is part of cdist.
#
@ -27,35 +27,33 @@ type="$(cat "$__object/parameter/type")"
source="$(cat "$__object/parameter/source")"
case "$type" in
symbolic)
lnopt="-s"
;;
hard)
lnopt=""
;;
*)
echo "Unknown type: $type" >&2
exit 1
;;
symbolic)
lnopt="-s"
;;
hard)
lnopt=""
;;
*)
echo "Unknown link type: $type" >&2
exit 1
;;
esac
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")"
if [ "$state_should" = "$state_is" ]; then
# nothing to do
exit 0
fi
[ "$state_should" = "$state_is" ] && exit 0
case "$state_should" in
present)
echo ln ${lnopt} -f \"$source\" \"$destination\"
;;
absent)
echo rm -f \"$destination\"
;;
*)
echo "Unknown state: $state_should" >&2
exit 1
;;
present)
echo ln ${lnopt} -f \"$source\" \"$destination\"
;;
absent)
echo rm -f \"$destination\"
;;
*)
echo "Unknown state: $state_should" >&2
exit 1
;;
esac

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