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 .*.swp
# Ignore generated manpages # Ignore generated manpages
doc/man/.marker docs/man/.marker
doc/man/man1/*.1 docs/man/man1/*.1
doc/man/man7/*.7 docs/man/man7/*.7
doc/man/man*/*.html docs/man/man*/*.html
doc/man/man*/*.xml docs/man/man*/*.xml
doc/man/man7/cdist-type__*.text docs/man/man*/docbook-xsl.css
doc/man/man7/cdist-reference.text docs/man/man7/cdist-type__*.text
doc/man/man*/docbook-xsl.css docs/man/man7/cdist-reference.text
# Ignore cdist cache for version control # Ignore cdist cache for version control
/cache/ /cache/
# Python / cache # Python: cache, distutils, distribution in general
__pycache__/ __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"]] cdist
-----
.. . .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 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 -*- # -*- 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. # This file is part of cdist.
# #
@ -20,215 +20,14 @@
# #
# #
def commandline(): # Wrapper for real script to allow execution from checkout
"""Parse command line""" dir=${0%/*}
import argparse
import cdist.banner # Ensure version is present - the bundled/shipped version contains a static version,
import cdist.config # the git version contains a dynamic version
import cdist.install "$dir/../build" version
# Construct parser others can reuse libdir=$(cd "${dir}/../" && pwd -P)
parser = {} export PYTHONPATH="${libdir}"
# 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)
# Main subcommand parser "$dir/../scripts/cdist" "$@"
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)

466
build
View file

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

View file

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

View file

@ -1,6 +1,7 @@
#!/bin/sh #!/bin/sh
# #
# 2010-2011 Nico Schottelius (nico-cdist at schottelius.org) # 2010-2011 Nico Schottelius (nico-cdist at schottelius.org)
# 2012 Steven Armstrong (steven-cdist at armstrong.cc)
# #
# This file is part of cdist. # 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") (. /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 if [ -x "$lsb_release" ]; then
$lsb_release --short --codename $lsb_release --short --codename
fi fi

View file

@ -25,7 +25,7 @@ case "$($__explorer/os)" in
(. /etc/openwrt_release && echo "$DISTRIB_DESCRIPTION") (. /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 if [ -x "$lsb_release" ]; then
$lsb_release --short --description $lsb_release --short --description
fi fi

View file

@ -25,7 +25,7 @@ case "$($__explorer/os)" in
(. /etc/openwrt_release && echo "$DISTRIB_ID") (. /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 if [ -x "$lsb_release" ]; then
$lsb_release --short --id $lsb_release --short --id
fi fi

View file

@ -25,7 +25,7 @@ case "$($__explorer/os)" in
(. /etc/openwrt_release && echo "$DISTRIB_RELEASE") (. /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 if [ -x "$lsb_release" ]; then
$lsb_release --short --release $lsb_release --short --release
fi 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 set +e
executable=$(which runlevel 2>/dev/null) executable=$(command -v runlevel)
if [ -x "$executable" ]; then if [ -x "$executable" ]; then
"$executable" | awk '{ print $2 }' "$executable" | awk '{ print $2 }'
fi 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 . /etc/lsb-release
repo_name="${name#ppa:}" 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}" ] \ [ -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_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
case "$state_should" in # Nothing to do, move along
enabled) exit 0
echo add-apt-repository \"$name\"
;;
disabled)
echo remove-apt-repository \"$name\"
;;
esac
fi 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 REQUIRED PARAMETERS
------------------- -------------------
state:: 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 OPTIONAL PARAMETERS
@ -29,10 +29,10 @@ EXAMPLES
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
# Enable a ppa repository # 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 # 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" name="$__object_id"
__package python-software-properties --state installed __package python-software-properties --state present
require="__package/python-software-properties" \ require="__package/python-software-properties" \
__file /usr/local/bin/remove-apt-repository \ __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 # run 'apt-get update' if anything in /etc/apt is newer then /var/lib/apt/lists
cat << DONE 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 apt-get update || apt-get update
fi fi
DONE DONE

View file

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

View file

@ -24,7 +24,7 @@ user="$(cat "$__object/parameter/user")"
prefix="#cdist:__cron/$name" prefix="#cdist:__cron/$name"
suffix="#/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)) { if (index($0,prefix)) {
triggered=1 triggered=1

View file

@ -18,6 +18,7 @@
# 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")"
user="$(cat "$__object/parameter/user")" user="$(cat "$__object/parameter/user")"
state_should="$(cat "$__object/parameter/state")" state_should="$(cat "$__object/parameter/state")"
state_is=$(diff -q "$__object/parameter/entry" "$__object/explorer/entry" \ 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 || 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 if [ "$state_is" != "$state_should" ]; then
case "$state_should" in case "$state_should" in
present) present)
cat << DONE cat << DONE
tmp=\$(mktemp) tmp=\$($mktemp)
crontab -u $user -l > \$tmp crontab -u $user -l > \$tmp
cat >> \$tmp << EOC cat >> \$tmp << EOC
$(cat "$__object/parameter/entry")" $(cat "$__object/parameter/entry")
EOC EOC
crontab -u $user \$tmp crontab -u $user \$tmp
rm \$tmp rm \$tmp

View file

@ -24,7 +24,7 @@
destination="/$__object_id" destination="/$__object_id"
if [ -e "$destination" ]; then if [ -e "$destination" ]; then
echo yes echo present
else else
echo no echo absent
fi 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:: owner::
User to chown to. User to chown to.
BOOLEAN PARAMETERS
------------------
parents:: 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:: recursive::
If supplied the chgrp and chown call will run recursively. If supplied the chgrp and chown call will run recursively.
This does *not* influence the behaviour of chmod. This does *not* influence the behaviour of chmod.
Must be yes or no.
EXAMPLES EXAMPLES
@ -55,13 +57,18 @@ __directory /tmp/foobar --state absent
__directory /etc --owner root --group root --mode 0755 __directory /etc --owner root --group root --mode 0755
# Create nfs service directory, including parents # Create nfs service directory, including parents
__directory /home/services/nfs --parents yes __directory /home/services/nfs --parents
# Change permissions recursively # Change permissions recursively
__directory /home/services --recursive yes --owner root --group root __directory /home/services --recursive --owner root --group root
# Setup a temp directory # Setup a temp directory
__directory /local --mode 1777 __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 group
mode mode
owner owner
parents
recursive

View file

@ -1,6 +1,6 @@
#!/bin/sh #!/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. # This file is part of cdist.
# #
@ -24,11 +24,11 @@
destination="/$__object_id" destination="/$__object_id"
if [ -e "$destination" ]; then if [ -e "$destination" ]; then
if [ -f "$destination" ]; then if [ -f "$destination" ]; then
cksum < "$destination" cksum < "$destination"
else else
echo "NO REGULAR FILE" echo "NO REGULAR FILE"
fi fi
else else
echo "NO FILE FOUND, NO CHECKSUM CALCULATED." echo "NO FILE FOUND, NO CHECKSUM CALCULATED."
fi 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 #!/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. # This file is part of cdist.
# #
@ -22,11 +22,18 @@
# #
destination="/$__object_id" 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 if [ -f "$__object/parameter/source" ]; then
source="$(cat "$__object/parameter/source")" source="$(cat "$__object/parameter/source")"
if [ "$source" = "-" ]; then
source="$__object/stdin"
fi
if [ -f "$source" ]; then if [ -f "$source" ]; then
local_cksum="$(cksum < "$source")" local_cksum="$(cksum < "$source")"

View file

@ -1,6 +1,6 @@
#!/bin/sh #!/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. # This file is part of cdist.
# #
@ -22,11 +22,12 @@
# #
destination="/$__object_id" 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")" exists="$(cat "$__object/explorer/exists")"
case "$state_should" in case "$state_should" in
present) present|exists)
# No source? Create empty file # No source? Create empty file
if [ ! -f "$__object/parameter/source" ]; then if [ ! -f "$__object/parameter/source" ]; then
if [ "$exists" = "no" ]; then if [ "$exists" = "no" ]; then

View file

@ -21,7 +21,11 @@ None.
OPTIONAL PARAMETERS OPTIONAL PARAMETERS
------------------- -------------------
state:: 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::
Group to chgrp to. Group to chgrp to.
@ -35,6 +39,7 @@ owner::
source:: source::
If supplied, copy this file from the host running cdist to the target. 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 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 EXAMPLES
@ -55,6 +60,17 @@ __file /etc/issue --source "$__type/files/archlinux" --state present
__file /etc/shadow --source "$__type/files/shadow" \ __file /etc/shadow --source "$__type/files/shadow" \
--owner root --group shadow --mode 0640 \ --owner root --group shadow --mode 0640 \
--state present --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 name=$__object_id
os_version="$($__explorer/os_version)" 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 case "$os_version" in
"Red Hat Enterprise Linux Server release "[45]*|"CentOS release "[45]*) "Red Hat Enterprise Linux Server release "[45]*|"CentOS release "[45]*)

View file

@ -24,6 +24,7 @@
name="$__object_id" name="$__object_id"
os_version="$(cat "$__global/explorer/os_version")" os_version="$(cat "$__global/explorer/os_version")"
os="$(cat "$__global/explorer/os")"
cd "$__object/parameter" cd "$__object/parameter"
if grep -q "^${name}:" "$__object/explorer/group"; then if grep -q "^${name}:" "$__object/explorer/group"; then
@ -35,7 +36,10 @@ if grep -q "^${name}:" "$__object/explorer/group"; then
case "$property" in case "$property" in
password) 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 case "$os_version" in
"Red Hat Enterprise Linux Server release "[45]*|"CentOS release "[45]*) "Red Hat Enterprise Linux Server release "[45]*|"CentOS release "[45]*)
# TODO: Use gpasswd? Need to fix gshadow explorer first. # TODO: Use gpasswd? Need to fix gshadow explorer first.
@ -43,6 +47,7 @@ if grep -q "^${name}:" "$__object/explorer/group"; then
exit 1 exit 1
;; ;;
esac esac
current_value="$(awk -F: '{ print $2 }' < "$__object/explorer/gshadow")"
;; ;;
gid) gid)
# set to -g to support older redhat/centos # set to -g to support older redhat/centos
@ -57,15 +62,48 @@ if grep -q "^${name}:" "$__object/explorer/group"; then
done done
if [ $# -gt 0 ]; then if [ $# -gt 0 ]; then
echo groupmod "$@" "$name" case $os in
else freebsd)
true echo pw group mod "$@" "$name"
;;
*)
echo groupmod "$@" "$name"
;;
esac
fi fi
else else
for property in $(ls .); do for property in $(ls .); do
new_value="$(cat "$property")" 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 done
echo groupadd "$@" "$name" case $os in
freebsd)
echo pw group add "$@" "$name"
;;
*)
echo groupadd "$@" "$name"
;;
esac
fi fi

View file

@ -1,6 +1,6 @@
#!/bin/sh #!/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. # This file is part of cdist.
# #
@ -24,17 +24,16 @@ destination=/etc/issue
os="$(cat "$__global/explorer/os")" os="$(cat "$__global/explorer/os")"
if [ -f "$__object/parameter/source" ]; then if [ -f "$__object/parameter/source" ]; then
source="$(cat "$__object/parameter/source")" source="$(cat "$__object/parameter/source")"
echo using $source
else else
case "$os" in case "$os" in
archlinux|redhat) archlinux|redhat)
source="$__type/files/$os" source="$__type/files/$os"
;; ;;
*) *)
source="$__type/files/default" source="$__type/files/default"
;; ;;
esac esac
fi fi
__file "$destination" --source "$source" __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 #!/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. # This file is part of cdist.
# #
@ -18,16 +18,26 @@
# along with cdist. If not, see <http://www.gnu.org/licenses/>. # along with cdist. If not, see <http://www.gnu.org/licenses/>.
# #
# #
# See if the requested jail exists
#
if [ -f "$__object/parameter/file" ]; then # Debug
file=$(cat "$__object/parameter/file") #exec >&2
#set -x
if [ -f "$__object/parameter/name" ]; then
name="$(cat "$__object/parameter/name")"
else else
file="/$__object_id" name=$__object_id
fi fi
result=$(cat "$__object/explorer/findline") if [ -f "$__object/parameter/jaildir" ]; then
jaildir="$(cat "$__object/parameter/name")"
if [ "$result" = "NOTFOUND" ]; then else
line=$(cat "$__object/parameter/line") jaildir="/usr/jail"
echo "echo $line >> $file"
fi 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/>. # along with cdist. If not, see <http://www.gnu.org/licenses/>.
# #
# set default: present, if not setup state_should=present
statefile="$__object/parameter/state" [ -f "$__object/parameter/state" ] && state_should="$(cat "$__object/parameter/state")"
[ -f "$statefile" ] || echo present > "$statefile"
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 #!/bin/sh
# #
# 2010-2011 Daniel Roth (dani-cdist@d-roth.li) # 2012 Nico Schottelius (nico-cdist at schottelius.org)
# 2011 Nico Schottelius (nico-cdist at schottelius.org)
# #
# This file is part of cdist. # This file is part of cdist.
# #
@ -20,29 +19,22 @@
# #
# #
if [ -f "$__object/parameter/file" ]; then file="/$__object_id"
file=$(cat "$__object/parameter/file") [ -f "$__object/parameter/file" ] && file=$(cat "$__object/parameter/file")
else
file="/$__object_id"
fi
if [ -f "$__object/parameter/regex" ]; then if [ -f "$__object/parameter/regex" ]; then
regex=$(cat "$__object/parameter/regex") regex=$(cat "$__object/parameter/regex")
else else
wrap=$(cat "$__object/parameter/line") if [ ! -f "$__object/parameter/line" ]; then
regex="^$wrap\$" echo "Parameter line and regex missing - cannot explore" >&2
exit 1
fi
regex="^$(cat "$__object/parameter/line")\$"
fi fi
if [ -f "$file" ]; then # Allow missing file - thus 2>/dev/null
# sh -e is our environment, we know what we do, if grep -q "$regex" "$file" 2>/dev/null; then
# skip error detection for now echo present
set +e
grep -q "$regex" "$file"
if [ $? -eq 1 ]; then
echo "NOTFOUND"
else
echo "FOUND"
fi
else else
echo "NOTFOUND" echo absent
fi 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,2 +1,4 @@
file state
regex regex
file
line

View file

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

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